History

Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6

Pull crypto fix from Herbert Xu: "This fixes a hash corruption bug in the marvell driver" * 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6: crypto: marvell - Copy IVDIG before launching partial DMA ahash requests

Linus Torvalds committed 9 years ago

Commit 2d706e72 parents 8f18e4d 8759fec3 files · +43 −3Browse files

Unified · Split

3 files
  1. drivers/crypto/marvell/cesa.h +2 −1
  2. drivers/crypto/marvell/hash.c +33 −1
  3. drivers/crypto/marvell/tdma.c +8 −1
drivers/crypto/marvell/cesa.h+2−1
@@ -273,7 +273,8 @@ struct mv_cesa_op_ctx { · 272 unmodified lines
273#define CESA_TDMA_SRC_IN_SRAM BIT(30)273#define CESA_TDMA_SRC_IN_SRAM BIT(30)
274#define CESA_TDMA_END_OF_REQ BIT(29)274#define CESA_TDMA_END_OF_REQ BIT(29)
275#define CESA_TDMA_BREAK_CHAIN BIT(28)275#define CESA_TDMA_BREAK_CHAIN BIT(28)
276#define CESA_TDMA_TYPE_MSK GENMASK(27, 0)276#define CESA_TDMA_SET_STATE BIT(27)
277#define CESA_TDMA_TYPE_MSK GENMASK(26, 0)
277#define CESA_TDMA_DUMMY 0278#define CESA_TDMA_DUMMY 0
278#define CESA_TDMA_DATA 1279#define CESA_TDMA_DATA 1
279#define CESA_TDMA_OP 2280#define CESA_TDMA_OP 2
drivers/crypto/marvell/hash.c+33−1
@@ -280,13 +280,32 @@ static void mv_cesa_ahash_std_prepare(struct ahash_request *req) · 279 unmodified lines
280 sreq->offset = 0;280 sreq->offset = 0;
281}281}
282 282
283static void mv_cesa_ahash_dma_step(struct ahash_request *req)
284{
285 struct mv_cesa_ahash_req *creq = ahash_request_ctx(req);
286 struct mv_cesa_req *base = &creq->base;
287
288 /* We must explicitly set the digest state. */
289 if (base->chain.first->flags & CESA_TDMA_SET_STATE) {
290 struct mv_cesa_engine *engine = base->engine;
291 int i;
292
293 /* Set the hash state in the IVDIG regs. */
294 for (i = 0; i < ARRAY_SIZE(creq->state); i++)
295 writel_relaxed(creq->state[i], engine->regs +
296 CESA_IVDIG(i));
297 }
298
299 mv_cesa_dma_step(base);
300}
301
283static void mv_cesa_ahash_step(struct crypto_async_request *req)302static void mv_cesa_ahash_step(struct crypto_async_request *req)
284{303{
285 struct ahash_request *ahashreq = ahash_request_cast(req);304 struct ahash_request *ahashreq = ahash_request_cast(req);
286 struct mv_cesa_ahash_req *creq = ahash_request_ctx(ahashreq);305 struct mv_cesa_ahash_req *creq = ahash_request_ctx(ahashreq);
287 306
288 if (mv_cesa_req_get_type(&creq->base) == CESA_DMA_REQ)307 if (mv_cesa_req_get_type(&creq->base) == CESA_DMA_REQ)
289 mv_cesa_dma_step(&creq->base);308 mv_cesa_ahash_dma_step(ahashreq);
290 else309 else
291 mv_cesa_ahash_std_step(ahashreq);310 mv_cesa_ahash_std_step(ahashreq);
292}311}
@@ -584,12 +603,16 @@ static int mv_cesa_ahash_dma_req_init(struct ahash_request *req) · 291 unmodified lines
584 struct mv_cesa_ahash_dma_iter iter;603 struct mv_cesa_ahash_dma_iter iter;
585 struct mv_cesa_op_ctx *op = NULL;604 struct mv_cesa_op_ctx *op = NULL;
586 unsigned int frag_len;605 unsigned int frag_len;
606 bool set_state = false;
587 int ret;607 int ret;
588 u32 type;608 u32 type;
589 609
590 basereq->chain.first = NULL;610 basereq->chain.first = NULL;
591 basereq->chain.last = NULL;611 basereq->chain.last = NULL;
592 612
613 if (!mv_cesa_mac_op_is_first_frag(&creq->op_tmpl))
614 set_state = true;
615
593 if (creq->src_nents) {616 if (creq->src_nents) {
594 ret = dma_map_sg(cesa_dev->dev, req->src, creq->src_nents,617 ret = dma_map_sg(cesa_dev->dev, req->src, creq->src_nents,
595 DMA_TO_DEVICE);618 DMA_TO_DEVICE);
@@ -683,6 +706,15 @@ static int mv_cesa_ahash_dma_req_init(struct ahash_request *req) · 87 unmodified lines
683 if (type != CESA_TDMA_RESULT)706 if (type != CESA_TDMA_RESULT)
684 basereq->chain.last->flags |= CESA_TDMA_BREAK_CHAIN;707 basereq->chain.last->flags |= CESA_TDMA_BREAK_CHAIN;
685 708
709 if (set_state) {
710 /*
711 * Put the CESA_TDMA_SET_STATE flag on the first tdma desc to
712 * let the step logic know that the IVDIG registers should be
713 * explicitly set before launching a TDMA chain.
714 */
715 basereq->chain.first->flags |= CESA_TDMA_SET_STATE;
716 }
717
686 return 0;718 return 0;
687 719
688err_free_tdma:720err_free_tdma:
drivers/crypto/marvell/tdma.c+8−1
@@ -109,7 +109,14 @@ void mv_cesa_tdma_chain(struct mv_cesa_engine *engine, · 108 unmodified lines
109 last->next = dreq->chain.first;109 last->next = dreq->chain.first;
110 engine->chain.last = dreq->chain.last;110 engine->chain.last = dreq->chain.last;
111 111
112 if (!(last->flags & CESA_TDMA_BREAK_CHAIN))112 /*
113 * Break the DMA chain if the CESA_TDMA_BREAK_CHAIN is set on
114 * the last element of the current chain, or if the request
115 * being queued needs the IV regs to be set before lauching
116 * the request.
117 */
118 if (!(last->flags & CESA_TDMA_BREAK_CHAIN) &&
119 !(dreq->chain.first->flags & CESA_TDMA_SET_STATE))
113 last->next_dma = dreq->chain.first->cur_dma;120 last->next_dma = dreq->chain.first->cur_dma;
114 }121 }
115}122}