aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crypto/algif_aead.c59
-rw-r--r--crypto/mcryptd.c19
-rw-r--r--drivers/crypto/caam/ctrl.c5
-rw-r--r--drivers/crypto/marvell/hash.c11
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
87static void aead_reset_ctx(struct aead_ctx *ctx) 91static 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
257static inline void mcryptd_check_internal(struct rtattr **tb, u32 *type, 257static 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
271static int mcryptd_hash_init_tfm(struct crypto_tfm *tfm) 275static 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,