diff options
-rw-r--r-- | crypto/algif_aead.c | 59 | ||||
-rw-r--r-- | crypto/mcryptd.c | 19 | ||||
-rw-r--r-- | drivers/crypto/caam/ctrl.c | 5 | ||||
-rw-r--r-- | drivers/crypto/marvell/hash.c | 11 |
4 files changed, 57 insertions, 37 deletions
diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c index 80a0f1a78551..e9c0993b131d 100644 --- a/crypto/algif_aead.c +++ b/crypto/algif_aead.c | |||
@@ -81,7 +81,11 @@ static inline bool aead_sufficient_data(struct aead_ctx *ctx) | |||
81 | { | 81 | { |
82 | unsigned as = crypto_aead_authsize(crypto_aead_reqtfm(&ctx->aead_req)); | 82 | unsigned as = crypto_aead_authsize(crypto_aead_reqtfm(&ctx->aead_req)); |
83 | 83 | ||
84 | return ctx->used >= ctx->aead_assoclen + as; | 84 | /* |
85 | * The minimum amount of memory needed for an AEAD cipher is | ||
86 | * the AAD and in case of decryption the tag. | ||
87 | */ | ||
88 | return ctx->used >= ctx->aead_assoclen + (ctx->enc ? 0 : as); | ||
85 | } | 89 | } |
86 | 90 | ||
87 | static void aead_reset_ctx(struct aead_ctx *ctx) | 91 | static void aead_reset_ctx(struct aead_ctx *ctx) |
@@ -416,7 +420,7 @@ static int aead_recvmsg_async(struct socket *sock, struct msghdr *msg, | |||
416 | unsigned int i, reqlen = GET_REQ_SIZE(tfm); | 420 | unsigned int i, reqlen = GET_REQ_SIZE(tfm); |
417 | int err = -ENOMEM; | 421 | int err = -ENOMEM; |
418 | unsigned long used; | 422 | unsigned long used; |
419 | size_t outlen; | 423 | size_t outlen = 0; |
420 | size_t usedpages = 0; | 424 | size_t usedpages = 0; |
421 | 425 | ||
422 | lock_sock(sk); | 426 | lock_sock(sk); |
@@ -426,12 +430,15 @@ static int aead_recvmsg_async(struct socket *sock, struct msghdr *msg, | |||
426 | goto unlock; | 430 | goto unlock; |
427 | } | 431 | } |
428 | 432 | ||
429 | used = ctx->used; | ||
430 | outlen = used; | ||
431 | |||
432 | if (!aead_sufficient_data(ctx)) | 433 | if (!aead_sufficient_data(ctx)) |
433 | goto unlock; | 434 | goto unlock; |
434 | 435 | ||
436 | used = ctx->used; | ||
437 | if (ctx->enc) | ||
438 | outlen = used + as; | ||
439 | else | ||
440 | outlen = used - as; | ||
441 | |||
435 | req = sock_kmalloc(sk, reqlen, GFP_KERNEL); | 442 | req = sock_kmalloc(sk, reqlen, GFP_KERNEL); |
436 | if (unlikely(!req)) | 443 | if (unlikely(!req)) |
437 | goto unlock; | 444 | goto unlock; |
@@ -445,7 +452,7 @@ static int aead_recvmsg_async(struct socket *sock, struct msghdr *msg, | |||
445 | aead_request_set_ad(req, ctx->aead_assoclen); | 452 | aead_request_set_ad(req, ctx->aead_assoclen); |
446 | aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, | 453 | aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, |
447 | aead_async_cb, sk); | 454 | aead_async_cb, sk); |
448 | used -= ctx->aead_assoclen + (ctx->enc ? as : 0); | 455 | used -= ctx->aead_assoclen; |
449 | 456 | ||
450 | /* take over all tx sgls from ctx */ | 457 | /* take over all tx sgls from ctx */ |
451 | areq->tsgl = sock_kmalloc(sk, sizeof(*areq->tsgl) * sgl->cur, | 458 | areq->tsgl = sock_kmalloc(sk, sizeof(*areq->tsgl) * sgl->cur, |
@@ -461,7 +468,7 @@ static int aead_recvmsg_async(struct socket *sock, struct msghdr *msg, | |||
461 | areq->tsgls = sgl->cur; | 468 | areq->tsgls = sgl->cur; |
462 | 469 | ||
463 | /* create rx sgls */ | 470 | /* create rx sgls */ |
464 | while (iov_iter_count(&msg->msg_iter)) { | 471 | while (outlen > usedpages && iov_iter_count(&msg->msg_iter)) { |
465 | size_t seglen = min_t(size_t, iov_iter_count(&msg->msg_iter), | 472 | size_t seglen = min_t(size_t, iov_iter_count(&msg->msg_iter), |
466 | (outlen - usedpages)); | 473 | (outlen - usedpages)); |
467 | 474 | ||
@@ -491,16 +498,14 @@ static int aead_recvmsg_async(struct socket *sock, struct msghdr *msg, | |||
491 | 498 | ||
492 | last_rsgl = rsgl; | 499 | last_rsgl = rsgl; |
493 | 500 | ||
494 | /* we do not need more iovecs as we have sufficient memory */ | ||
495 | if (outlen <= usedpages) | ||
496 | break; | ||
497 | |||
498 | iov_iter_advance(&msg->msg_iter, err); | 501 | iov_iter_advance(&msg->msg_iter, err); |
499 | } | 502 | } |
500 | err = -EINVAL; | 503 | |
501 | /* ensure output buffer is sufficiently large */ | 504 | /* ensure output buffer is sufficiently large */ |
502 | if (usedpages < outlen) | 505 | if (usedpages < outlen) { |
503 | goto free; | 506 | err = -EINVAL; |
507 | goto unlock; | ||
508 | } | ||
504 | 509 | ||
505 | aead_request_set_crypt(req, areq->tsgl, areq->first_rsgl.sgl.sg, used, | 510 | aead_request_set_crypt(req, areq->tsgl, areq->first_rsgl.sgl.sg, used, |
506 | areq->iv); | 511 | areq->iv); |
@@ -571,6 +576,7 @@ static int aead_recvmsg_sync(struct socket *sock, struct msghdr *msg, int flags) | |||
571 | goto unlock; | 576 | goto unlock; |
572 | } | 577 | } |
573 | 578 | ||
579 | /* data length provided by caller via sendmsg/sendpage */ | ||
574 | used = ctx->used; | 580 | used = ctx->used; |
575 | 581 | ||
576 | /* | 582 | /* |
@@ -585,16 +591,27 @@ static int aead_recvmsg_sync(struct socket *sock, struct msghdr *msg, int flags) | |||
585 | if (!aead_sufficient_data(ctx)) | 591 | if (!aead_sufficient_data(ctx)) |
586 | goto unlock; | 592 | goto unlock; |
587 | 593 | ||
588 | outlen = used; | 594 | /* |
595 | * Calculate the minimum output buffer size holding the result of the | ||
596 | * cipher operation. When encrypting data, the receiving buffer is | ||
597 | * larger by the tag length compared to the input buffer as the | ||
598 | * encryption operation generates the tag. For decryption, the input | ||
599 | * buffer provides the tag which is consumed resulting in only the | ||
600 | * plaintext without a buffer for the tag returned to the caller. | ||
601 | */ | ||
602 | if (ctx->enc) | ||
603 | outlen = used + as; | ||
604 | else | ||
605 | outlen = used - as; | ||
589 | 606 | ||
590 | /* | 607 | /* |
591 | * The cipher operation input data is reduced by the associated data | 608 | * The cipher operation input data is reduced by the associated data |
592 | * length as this data is processed separately later on. | 609 | * length as this data is processed separately later on. |
593 | */ | 610 | */ |
594 | used -= ctx->aead_assoclen + (ctx->enc ? as : 0); | 611 | used -= ctx->aead_assoclen; |
595 | 612 | ||
596 | /* convert iovecs of output buffers into scatterlists */ | 613 | /* convert iovecs of output buffers into scatterlists */ |
597 | while (iov_iter_count(&msg->msg_iter)) { | 614 | while (outlen > usedpages && iov_iter_count(&msg->msg_iter)) { |
598 | size_t seglen = min_t(size_t, iov_iter_count(&msg->msg_iter), | 615 | size_t seglen = min_t(size_t, iov_iter_count(&msg->msg_iter), |
599 | (outlen - usedpages)); | 616 | (outlen - usedpages)); |
600 | 617 | ||
@@ -621,16 +638,14 @@ static int aead_recvmsg_sync(struct socket *sock, struct msghdr *msg, int flags) | |||
621 | 638 | ||
622 | last_rsgl = rsgl; | 639 | last_rsgl = rsgl; |
623 | 640 | ||
624 | /* we do not need more iovecs as we have sufficient memory */ | ||
625 | if (outlen <= usedpages) | ||
626 | break; | ||
627 | iov_iter_advance(&msg->msg_iter, err); | 641 | iov_iter_advance(&msg->msg_iter, err); |
628 | } | 642 | } |
629 | 643 | ||
630 | err = -EINVAL; | ||
631 | /* ensure output buffer is sufficiently large */ | 644 | /* ensure output buffer is sufficiently large */ |
632 | if (usedpages < outlen) | 645 | if (usedpages < outlen) { |
646 | err = -EINVAL; | ||
633 | goto unlock; | 647 | goto unlock; |
648 | } | ||
634 | 649 | ||
635 | sg_mark_end(sgl->sg + sgl->cur - 1); | 650 | sg_mark_end(sgl->sg + sgl->cur - 1); |
636 | aead_request_set_crypt(&ctx->aead_req, sgl->sg, ctx->first_rsgl.sgl.sg, | 651 | aead_request_set_crypt(&ctx->aead_req, sgl->sg, ctx->first_rsgl.sgl.sg, |
diff --git a/crypto/mcryptd.c b/crypto/mcryptd.c index 94ee44acd465..c207458d6299 100644 --- a/crypto/mcryptd.c +++ b/crypto/mcryptd.c | |||
@@ -254,18 +254,22 @@ out_free_inst: | |||
254 | goto out; | 254 | goto out; |
255 | } | 255 | } |
256 | 256 | ||
257 | static inline void mcryptd_check_internal(struct rtattr **tb, u32 *type, | 257 | static inline bool mcryptd_check_internal(struct rtattr **tb, u32 *type, |
258 | u32 *mask) | 258 | u32 *mask) |
259 | { | 259 | { |
260 | struct crypto_attr_type *algt; | 260 | struct crypto_attr_type *algt; |
261 | 261 | ||
262 | algt = crypto_get_attr_type(tb); | 262 | algt = crypto_get_attr_type(tb); |
263 | if (IS_ERR(algt)) | 263 | if (IS_ERR(algt)) |
264 | return; | 264 | return false; |
265 | if ((algt->type & CRYPTO_ALG_INTERNAL)) | 265 | |
266 | *type |= CRYPTO_ALG_INTERNAL; | 266 | *type |= algt->type & CRYPTO_ALG_INTERNAL; |
267 | if ((algt->mask & CRYPTO_ALG_INTERNAL)) | 267 | *mask |= algt->mask & CRYPTO_ALG_INTERNAL; |
268 | *mask |= CRYPTO_ALG_INTERNAL; | 268 | |
269 | if (*type & *mask & CRYPTO_ALG_INTERNAL) | ||
270 | return true; | ||
271 | else | ||
272 | return false; | ||
269 | } | 273 | } |
270 | 274 | ||
271 | static int mcryptd_hash_init_tfm(struct crypto_tfm *tfm) | 275 | static int mcryptd_hash_init_tfm(struct crypto_tfm *tfm) |
@@ -492,7 +496,8 @@ static int mcryptd_create_hash(struct crypto_template *tmpl, struct rtattr **tb, | |||
492 | u32 mask = 0; | 496 | u32 mask = 0; |
493 | int err; | 497 | int err; |
494 | 498 | ||
495 | mcryptd_check_internal(tb, &type, &mask); | 499 | if (!mcryptd_check_internal(tb, &type, &mask)) |
500 | return -EINVAL; | ||
496 | 501 | ||
497 | halg = ahash_attr_alg(tb[1], type, mask); | 502 | halg = ahash_attr_alg(tb[1], type, mask); |
498 | if (IS_ERR(halg)) | 503 | if (IS_ERR(halg)) |
diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c index 72ff19658985..e483b78c6343 100644 --- a/drivers/crypto/caam/ctrl.c +++ b/drivers/crypto/caam/ctrl.c | |||
@@ -558,8 +558,9 @@ static int caam_probe(struct platform_device *pdev) | |||
558 | * Enable DECO watchdogs and, if this is a PHYS_ADDR_T_64BIT kernel, | 558 | * Enable DECO watchdogs and, if this is a PHYS_ADDR_T_64BIT kernel, |
559 | * long pointers in master configuration register | 559 | * long pointers in master configuration register |
560 | */ | 560 | */ |
561 | clrsetbits_32(&ctrl->mcr, MCFGR_AWCACHE_MASK, MCFGR_AWCACHE_CACH | | 561 | clrsetbits_32(&ctrl->mcr, MCFGR_AWCACHE_MASK | MCFGR_LONG_PTR, |
562 | MCFGR_AWCACHE_BUFF | MCFGR_WDENABLE | MCFGR_LARGE_BURST | | 562 | MCFGR_AWCACHE_CACH | MCFGR_AWCACHE_BUFF | |
563 | MCFGR_WDENABLE | MCFGR_LARGE_BURST | | ||
563 | (sizeof(dma_addr_t) == sizeof(u64) ? MCFGR_LONG_PTR : 0)); | 564 | (sizeof(dma_addr_t) == sizeof(u64) ? MCFGR_LONG_PTR : 0)); |
564 | 565 | ||
565 | /* | 566 | /* |
diff --git a/drivers/crypto/marvell/hash.c b/drivers/crypto/marvell/hash.c index 9f284682c091..77712b375b84 100644 --- a/drivers/crypto/marvell/hash.c +++ b/drivers/crypto/marvell/hash.c | |||
@@ -168,12 +168,11 @@ static void mv_cesa_ahash_std_step(struct ahash_request *req) | |||
168 | mv_cesa_adjust_op(engine, &creq->op_tmpl); | 168 | mv_cesa_adjust_op(engine, &creq->op_tmpl); |
169 | memcpy_toio(engine->sram, &creq->op_tmpl, sizeof(creq->op_tmpl)); | 169 | memcpy_toio(engine->sram, &creq->op_tmpl, sizeof(creq->op_tmpl)); |
170 | 170 | ||
171 | digsize = crypto_ahash_digestsize(crypto_ahash_reqtfm(req)); | 171 | if (!sreq->offset) { |
172 | for (i = 0; i < digsize / 4; i++) | 172 | digsize = crypto_ahash_digestsize(crypto_ahash_reqtfm(req)); |
173 | writel_relaxed(creq->state[i], engine->regs + CESA_IVDIG(i)); | 173 | for (i = 0; i < digsize / 4; i++) |
174 | 174 | writel_relaxed(creq->state[i], engine->regs + CESA_IVDIG(i)); | |
175 | mv_cesa_adjust_op(engine, &creq->op_tmpl); | 175 | } |
176 | memcpy_toio(engine->sram, &creq->op_tmpl, sizeof(creq->op_tmpl)); | ||
177 | 176 | ||
178 | if (creq->cache_ptr) | 177 | if (creq->cache_ptr) |
179 | memcpy_toio(engine->sram + CESA_SA_DATA_SRAM_OFFSET, | 178 | memcpy_toio(engine->sram + CESA_SA_DATA_SRAM_OFFSET, |