diff options
Diffstat (limited to 'crypto/cryptd.c')
-rw-r--r-- | crypto/cryptd.c | 164 |
1 files changed, 84 insertions, 80 deletions
diff --git a/crypto/cryptd.c b/crypto/cryptd.c index ae5fa99d5d36..ef5720cf1216 100644 --- a/crypto/cryptd.c +++ b/crypto/cryptd.c | |||
@@ -39,6 +39,11 @@ struct cryptd_instance_ctx { | |||
39 | struct cryptd_queue *queue; | 39 | struct cryptd_queue *queue; |
40 | }; | 40 | }; |
41 | 41 | ||
42 | struct hashd_instance_ctx { | ||
43 | struct crypto_shash_spawn spawn; | ||
44 | struct cryptd_queue *queue; | ||
45 | }; | ||
46 | |||
42 | struct cryptd_blkcipher_ctx { | 47 | struct cryptd_blkcipher_ctx { |
43 | struct crypto_blkcipher *child; | 48 | struct crypto_blkcipher *child; |
44 | }; | 49 | }; |
@@ -48,11 +53,12 @@ struct cryptd_blkcipher_request_ctx { | |||
48 | }; | 53 | }; |
49 | 54 | ||
50 | struct cryptd_hash_ctx { | 55 | struct cryptd_hash_ctx { |
51 | struct crypto_hash *child; | 56 | struct crypto_shash *child; |
52 | }; | 57 | }; |
53 | 58 | ||
54 | struct cryptd_hash_request_ctx { | 59 | struct cryptd_hash_request_ctx { |
55 | crypto_completion_t complete; | 60 | crypto_completion_t complete; |
61 | struct shash_desc desc; | ||
56 | }; | 62 | }; |
57 | 63 | ||
58 | static void cryptd_queue_worker(struct work_struct *work); | 64 | static void cryptd_queue_worker(struct work_struct *work); |
@@ -250,13 +256,12 @@ static void cryptd_blkcipher_exit_tfm(struct crypto_tfm *tfm) | |||
250 | } | 256 | } |
251 | 257 | ||
252 | static struct crypto_instance *cryptd_alloc_instance(struct crypto_alg *alg, | 258 | static struct crypto_instance *cryptd_alloc_instance(struct crypto_alg *alg, |
253 | struct cryptd_queue *queue) | 259 | unsigned int tail) |
254 | { | 260 | { |
255 | struct crypto_instance *inst; | 261 | struct crypto_instance *inst; |
256 | struct cryptd_instance_ctx *ctx; | ||
257 | int err; | 262 | int err; |
258 | 263 | ||
259 | inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL); | 264 | inst = kzalloc(sizeof(*inst) + tail, GFP_KERNEL); |
260 | if (!inst) { | 265 | if (!inst) { |
261 | inst = ERR_PTR(-ENOMEM); | 266 | inst = ERR_PTR(-ENOMEM); |
262 | goto out; | 267 | goto out; |
@@ -267,14 +272,6 @@ static struct crypto_instance *cryptd_alloc_instance(struct crypto_alg *alg, | |||
267 | "cryptd(%s)", alg->cra_driver_name) >= CRYPTO_MAX_ALG_NAME) | 272 | "cryptd(%s)", alg->cra_driver_name) >= CRYPTO_MAX_ALG_NAME) |
268 | goto out_free_inst; | 273 | goto out_free_inst; |
269 | 274 | ||
270 | ctx = crypto_instance_ctx(inst); | ||
271 | err = crypto_init_spawn(&ctx->spawn, alg, inst, | ||
272 | CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC); | ||
273 | if (err) | ||
274 | goto out_free_inst; | ||
275 | |||
276 | ctx->queue = queue; | ||
277 | |||
278 | memcpy(inst->alg.cra_name, alg->cra_name, CRYPTO_MAX_ALG_NAME); | 275 | memcpy(inst->alg.cra_name, alg->cra_name, CRYPTO_MAX_ALG_NAME); |
279 | 276 | ||
280 | inst->alg.cra_priority = alg->cra_priority + 50; | 277 | inst->alg.cra_priority = alg->cra_priority + 50; |
@@ -293,18 +290,28 @@ out_free_inst: | |||
293 | static struct crypto_instance *cryptd_alloc_blkcipher( | 290 | static struct crypto_instance *cryptd_alloc_blkcipher( |
294 | struct rtattr **tb, struct cryptd_queue *queue) | 291 | struct rtattr **tb, struct cryptd_queue *queue) |
295 | { | 292 | { |
293 | struct cryptd_instance_ctx *ctx; | ||
296 | struct crypto_instance *inst; | 294 | struct crypto_instance *inst; |
297 | struct crypto_alg *alg; | 295 | struct crypto_alg *alg; |
296 | int err; | ||
298 | 297 | ||
299 | alg = crypto_get_attr_alg(tb, CRYPTO_ALG_TYPE_BLKCIPHER, | 298 | alg = crypto_get_attr_alg(tb, CRYPTO_ALG_TYPE_BLKCIPHER, |
300 | CRYPTO_ALG_TYPE_MASK); | 299 | CRYPTO_ALG_TYPE_MASK); |
301 | if (IS_ERR(alg)) | 300 | if (IS_ERR(alg)) |
302 | return ERR_CAST(alg); | 301 | return ERR_CAST(alg); |
303 | 302 | ||
304 | inst = cryptd_alloc_instance(alg, queue); | 303 | inst = cryptd_alloc_instance(alg, sizeof(*ctx)); |
305 | if (IS_ERR(inst)) | 304 | if (IS_ERR(inst)) |
306 | goto out_put_alg; | 305 | goto out_put_alg; |
307 | 306 | ||
307 | ctx = crypto_instance_ctx(inst); | ||
308 | ctx->queue = queue; | ||
309 | |||
310 | err = crypto_init_spawn(&ctx->spawn, alg, inst, | ||
311 | CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC); | ||
312 | if (err) | ||
313 | goto out_free_inst; | ||
314 | |||
308 | inst->alg.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC; | 315 | inst->alg.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC; |
309 | inst->alg.cra_type = &crypto_ablkcipher_type; | 316 | inst->alg.cra_type = &crypto_ablkcipher_type; |
310 | 317 | ||
@@ -326,23 +333,28 @@ static struct crypto_instance *cryptd_alloc_blkcipher( | |||
326 | out_put_alg: | 333 | out_put_alg: |
327 | crypto_mod_put(alg); | 334 | crypto_mod_put(alg); |
328 | return inst; | 335 | return inst; |
336 | |||
337 | out_free_inst: | ||
338 | kfree(inst); | ||
339 | inst = ERR_PTR(err); | ||
340 | goto out_put_alg; | ||
329 | } | 341 | } |
330 | 342 | ||
331 | static int cryptd_hash_init_tfm(struct crypto_tfm *tfm) | 343 | static int cryptd_hash_init_tfm(struct crypto_tfm *tfm) |
332 | { | 344 | { |
333 | struct crypto_instance *inst = crypto_tfm_alg_instance(tfm); | 345 | struct crypto_instance *inst = crypto_tfm_alg_instance(tfm); |
334 | struct cryptd_instance_ctx *ictx = crypto_instance_ctx(inst); | 346 | struct hashd_instance_ctx *ictx = crypto_instance_ctx(inst); |
335 | struct crypto_spawn *spawn = &ictx->spawn; | 347 | struct crypto_shash_spawn *spawn = &ictx->spawn; |
336 | struct cryptd_hash_ctx *ctx = crypto_tfm_ctx(tfm); | 348 | struct cryptd_hash_ctx *ctx = crypto_tfm_ctx(tfm); |
337 | struct crypto_hash *cipher; | 349 | struct crypto_shash *hash; |
338 | 350 | ||
339 | cipher = crypto_spawn_hash(spawn); | 351 | hash = crypto_spawn_shash(spawn); |
340 | if (IS_ERR(cipher)) | 352 | if (IS_ERR(hash)) |
341 | return PTR_ERR(cipher); | 353 | return PTR_ERR(hash); |
342 | 354 | ||
343 | ctx->child = cipher; | 355 | ctx->child = hash; |
344 | tfm->crt_ahash.reqsize = | 356 | tfm->crt_ahash.reqsize = sizeof(struct cryptd_hash_request_ctx) + |
345 | sizeof(struct cryptd_hash_request_ctx); | 357 | crypto_shash_descsize(hash); |
346 | return 0; | 358 | return 0; |
347 | } | 359 | } |
348 | 360 | ||
@@ -350,22 +362,22 @@ static void cryptd_hash_exit_tfm(struct crypto_tfm *tfm) | |||
350 | { | 362 | { |
351 | struct cryptd_hash_ctx *ctx = crypto_tfm_ctx(tfm); | 363 | struct cryptd_hash_ctx *ctx = crypto_tfm_ctx(tfm); |
352 | 364 | ||
353 | crypto_free_hash(ctx->child); | 365 | crypto_free_shash(ctx->child); |
354 | } | 366 | } |
355 | 367 | ||
356 | static int cryptd_hash_setkey(struct crypto_ahash *parent, | 368 | static int cryptd_hash_setkey(struct crypto_ahash *parent, |
357 | const u8 *key, unsigned int keylen) | 369 | const u8 *key, unsigned int keylen) |
358 | { | 370 | { |
359 | struct cryptd_hash_ctx *ctx = crypto_ahash_ctx(parent); | 371 | struct cryptd_hash_ctx *ctx = crypto_ahash_ctx(parent); |
360 | struct crypto_hash *child = ctx->child; | 372 | struct crypto_shash *child = ctx->child; |
361 | int err; | 373 | int err; |
362 | 374 | ||
363 | crypto_hash_clear_flags(child, CRYPTO_TFM_REQ_MASK); | 375 | crypto_shash_clear_flags(child, CRYPTO_TFM_REQ_MASK); |
364 | crypto_hash_set_flags(child, crypto_ahash_get_flags(parent) & | 376 | crypto_shash_set_flags(child, crypto_ahash_get_flags(parent) & |
365 | CRYPTO_TFM_REQ_MASK); | 377 | CRYPTO_TFM_REQ_MASK); |
366 | err = crypto_hash_setkey(child, key, keylen); | 378 | err = crypto_shash_setkey(child, key, keylen); |
367 | crypto_ahash_set_flags(parent, crypto_hash_get_flags(child) & | 379 | crypto_ahash_set_flags(parent, crypto_shash_get_flags(child) & |
368 | CRYPTO_TFM_RES_MASK); | 380 | CRYPTO_TFM_RES_MASK); |
369 | return err; | 381 | return err; |
370 | } | 382 | } |
371 | 383 | ||
@@ -385,21 +397,19 @@ static int cryptd_hash_enqueue(struct ahash_request *req, | |||
385 | 397 | ||
386 | static void cryptd_hash_init(struct crypto_async_request *req_async, int err) | 398 | static void cryptd_hash_init(struct crypto_async_request *req_async, int err) |
387 | { | 399 | { |
388 | struct cryptd_hash_ctx *ctx = crypto_tfm_ctx(req_async->tfm); | 400 | struct cryptd_hash_ctx *ctx = crypto_tfm_ctx(req_async->tfm); |
389 | struct crypto_hash *child = ctx->child; | 401 | struct crypto_shash *child = ctx->child; |
390 | struct ahash_request *req = ahash_request_cast(req_async); | 402 | struct ahash_request *req = ahash_request_cast(req_async); |
391 | struct cryptd_hash_request_ctx *rctx; | 403 | struct cryptd_hash_request_ctx *rctx = ahash_request_ctx(req); |
392 | struct hash_desc desc; | 404 | struct shash_desc *desc = &rctx->desc; |
393 | |||
394 | rctx = ahash_request_ctx(req); | ||
395 | 405 | ||
396 | if (unlikely(err == -EINPROGRESS)) | 406 | if (unlikely(err == -EINPROGRESS)) |
397 | goto out; | 407 | goto out; |
398 | 408 | ||
399 | desc.tfm = child; | 409 | desc->tfm = child; |
400 | desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; | 410 | desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP; |
401 | 411 | ||
402 | err = crypto_hash_crt(child)->init(&desc); | 412 | err = crypto_shash_init(desc); |
403 | 413 | ||
404 | req->base.complete = rctx->complete; | 414 | req->base.complete = rctx->complete; |
405 | 415 | ||
@@ -416,23 +426,15 @@ static int cryptd_hash_init_enqueue(struct ahash_request *req) | |||
416 | 426 | ||
417 | static void cryptd_hash_update(struct crypto_async_request *req_async, int err) | 427 | static void cryptd_hash_update(struct crypto_async_request *req_async, int err) |
418 | { | 428 | { |
419 | struct cryptd_hash_ctx *ctx = crypto_tfm_ctx(req_async->tfm); | 429 | struct ahash_request *req = ahash_request_cast(req_async); |
420 | struct crypto_hash *child = ctx->child; | ||
421 | struct ahash_request *req = ahash_request_cast(req_async); | ||
422 | struct cryptd_hash_request_ctx *rctx; | 430 | struct cryptd_hash_request_ctx *rctx; |
423 | struct hash_desc desc; | ||
424 | 431 | ||
425 | rctx = ahash_request_ctx(req); | 432 | rctx = ahash_request_ctx(req); |
426 | 433 | ||
427 | if (unlikely(err == -EINPROGRESS)) | 434 | if (unlikely(err == -EINPROGRESS)) |
428 | goto out; | 435 | goto out; |
429 | 436 | ||
430 | desc.tfm = child; | 437 | err = shash_ahash_update(req, &rctx->desc); |
431 | desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; | ||
432 | |||
433 | err = crypto_hash_crt(child)->update(&desc, | ||
434 | req->src, | ||
435 | req->nbytes); | ||
436 | 438 | ||
437 | req->base.complete = rctx->complete; | 439 | req->base.complete = rctx->complete; |
438 | 440 | ||
@@ -449,21 +451,13 @@ static int cryptd_hash_update_enqueue(struct ahash_request *req) | |||
449 | 451 | ||
450 | static void cryptd_hash_final(struct crypto_async_request *req_async, int err) | 452 | static void cryptd_hash_final(struct crypto_async_request *req_async, int err) |
451 | { | 453 | { |
452 | struct cryptd_hash_ctx *ctx = crypto_tfm_ctx(req_async->tfm); | 454 | struct ahash_request *req = ahash_request_cast(req_async); |
453 | struct crypto_hash *child = ctx->child; | 455 | struct cryptd_hash_request_ctx *rctx = ahash_request_ctx(req); |
454 | struct ahash_request *req = ahash_request_cast(req_async); | ||
455 | struct cryptd_hash_request_ctx *rctx; | ||
456 | struct hash_desc desc; | ||
457 | |||
458 | rctx = ahash_request_ctx(req); | ||
459 | 456 | ||
460 | if (unlikely(err == -EINPROGRESS)) | 457 | if (unlikely(err == -EINPROGRESS)) |
461 | goto out; | 458 | goto out; |
462 | 459 | ||
463 | desc.tfm = child; | 460 | err = crypto_shash_final(&rctx->desc, req->result); |
464 | desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; | ||
465 | |||
466 | err = crypto_hash_crt(child)->final(&desc, req->result); | ||
467 | 461 | ||
468 | req->base.complete = rctx->complete; | 462 | req->base.complete = rctx->complete; |
469 | 463 | ||
@@ -480,24 +474,19 @@ static int cryptd_hash_final_enqueue(struct ahash_request *req) | |||
480 | 474 | ||
481 | static void cryptd_hash_digest(struct crypto_async_request *req_async, int err) | 475 | static void cryptd_hash_digest(struct crypto_async_request *req_async, int err) |
482 | { | 476 | { |
483 | struct cryptd_hash_ctx *ctx = crypto_tfm_ctx(req_async->tfm); | 477 | struct cryptd_hash_ctx *ctx = crypto_tfm_ctx(req_async->tfm); |
484 | struct crypto_hash *child = ctx->child; | 478 | struct crypto_shash *child = ctx->child; |
485 | struct ahash_request *req = ahash_request_cast(req_async); | 479 | struct ahash_request *req = ahash_request_cast(req_async); |
486 | struct cryptd_hash_request_ctx *rctx; | 480 | struct cryptd_hash_request_ctx *rctx = ahash_request_ctx(req); |
487 | struct hash_desc desc; | 481 | struct shash_desc *desc = &rctx->desc; |
488 | |||
489 | rctx = ahash_request_ctx(req); | ||
490 | 482 | ||
491 | if (unlikely(err == -EINPROGRESS)) | 483 | if (unlikely(err == -EINPROGRESS)) |
492 | goto out; | 484 | goto out; |
493 | 485 | ||
494 | desc.tfm = child; | 486 | desc->tfm = child; |
495 | desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; | 487 | desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP; |
496 | 488 | ||
497 | err = crypto_hash_crt(child)->digest(&desc, | 489 | err = shash_ahash_digest(req, desc); |
498 | req->src, | ||
499 | req->nbytes, | ||
500 | req->result); | ||
501 | 490 | ||
502 | req->base.complete = rctx->complete; | 491 | req->base.complete = rctx->complete; |
503 | 492 | ||
@@ -515,22 +504,32 @@ static int cryptd_hash_digest_enqueue(struct ahash_request *req) | |||
515 | static struct crypto_instance *cryptd_alloc_hash( | 504 | static struct crypto_instance *cryptd_alloc_hash( |
516 | struct rtattr **tb, struct cryptd_queue *queue) | 505 | struct rtattr **tb, struct cryptd_queue *queue) |
517 | { | 506 | { |
507 | struct hashd_instance_ctx *ctx; | ||
518 | struct crypto_instance *inst; | 508 | struct crypto_instance *inst; |
509 | struct shash_alg *salg; | ||
519 | struct crypto_alg *alg; | 510 | struct crypto_alg *alg; |
511 | int err; | ||
520 | 512 | ||
521 | alg = crypto_get_attr_alg(tb, CRYPTO_ALG_TYPE_HASH, | 513 | salg = shash_attr_alg(tb[1], 0, 0); |
522 | CRYPTO_ALG_TYPE_HASH_MASK); | 514 | if (IS_ERR(salg)) |
523 | if (IS_ERR(alg)) | 515 | return ERR_CAST(salg); |
524 | return ERR_PTR(PTR_ERR(alg)); | ||
525 | 516 | ||
526 | inst = cryptd_alloc_instance(alg, queue); | 517 | alg = &salg->base; |
518 | inst = cryptd_alloc_instance(alg, sizeof(*ctx)); | ||
527 | if (IS_ERR(inst)) | 519 | if (IS_ERR(inst)) |
528 | goto out_put_alg; | 520 | goto out_put_alg; |
529 | 521 | ||
522 | ctx = crypto_instance_ctx(inst); | ||
523 | ctx->queue = queue; | ||
524 | |||
525 | err = crypto_init_shash_spawn(&ctx->spawn, salg, inst); | ||
526 | if (err) | ||
527 | goto out_free_inst; | ||
528 | |||
530 | inst->alg.cra_flags = CRYPTO_ALG_TYPE_AHASH | CRYPTO_ALG_ASYNC; | 529 | inst->alg.cra_flags = CRYPTO_ALG_TYPE_AHASH | CRYPTO_ALG_ASYNC; |
531 | inst->alg.cra_type = &crypto_ahash_type; | 530 | inst->alg.cra_type = &crypto_ahash_type; |
532 | 531 | ||
533 | inst->alg.cra_ahash.digestsize = alg->cra_hash.digestsize; | 532 | inst->alg.cra_ahash.digestsize = salg->digestsize; |
534 | inst->alg.cra_ctxsize = sizeof(struct cryptd_hash_ctx); | 533 | inst->alg.cra_ctxsize = sizeof(struct cryptd_hash_ctx); |
535 | 534 | ||
536 | inst->alg.cra_init = cryptd_hash_init_tfm; | 535 | inst->alg.cra_init = cryptd_hash_init_tfm; |
@@ -545,6 +544,11 @@ static struct crypto_instance *cryptd_alloc_hash( | |||
545 | out_put_alg: | 544 | out_put_alg: |
546 | crypto_mod_put(alg); | 545 | crypto_mod_put(alg); |
547 | return inst; | 546 | return inst; |
547 | |||
548 | out_free_inst: | ||
549 | kfree(inst); | ||
550 | inst = ERR_PTR(err); | ||
551 | goto out_put_alg; | ||
548 | } | 552 | } |
549 | 553 | ||
550 | static struct cryptd_queue queue; | 554 | static struct cryptd_queue queue; |