Skip to content

Commit 2d706e7

Browse files
committed
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
2 parents 8f18e4d + 8759fec commit 2d706e7

File tree

3 files changed

+43
-3
lines changed

3 files changed

+43
-3
lines changed

drivers/crypto/marvell/cesa.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,8 @@ struct mv_cesa_op_ctx {
273273
#define CESA_TDMA_SRC_IN_SRAM BIT(30)
274274
#define CESA_TDMA_END_OF_REQ BIT(29)
275275
#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)
277278
#define CESA_TDMA_DUMMY 0
278279
#define CESA_TDMA_DATA 1
279280
#define CESA_TDMA_OP 2

drivers/crypto/marvell/hash.c

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,13 +280,32 @@ static void mv_cesa_ahash_std_prepare(struct ahash_request *req)
280280
sreq->offset = 0;
281281
}
282282

283+
static 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+
283302
static void mv_cesa_ahash_step(struct crypto_async_request *req)
284303
{
285304
struct ahash_request *ahashreq = ahash_request_cast(req);
286305
struct mv_cesa_ahash_req *creq = ahash_request_ctx(ahashreq);
287306

288307
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);
290309
else
291310
mv_cesa_ahash_std_step(ahashreq);
292311
}
@@ -584,12 +603,16 @@ static int mv_cesa_ahash_dma_req_init(struct ahash_request *req)
584603
struct mv_cesa_ahash_dma_iter iter;
585604
struct mv_cesa_op_ctx *op = NULL;
586605
unsigned int frag_len;
606+
bool set_state = false;
587607
int ret;
588608
u32 type;
589609

590610
basereq->chain.first = NULL;
591611
basereq->chain.last = NULL;
592612

613+
if (!mv_cesa_mac_op_is_first_frag(&creq->op_tmpl))
614+
set_state = true;
615+
593616
if (creq->src_nents) {
594617
ret = dma_map_sg(cesa_dev->dev, req->src, creq->src_nents,
595618
DMA_TO_DEVICE);
@@ -683,6 +706,15 @@ static int mv_cesa_ahash_dma_req_init(struct ahash_request *req)
683706
if (type != CESA_TDMA_RESULT)
684707
basereq->chain.last->flags |= CESA_TDMA_BREAK_CHAIN;
685708

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+
686718
return 0;
687719

688720
err_free_tdma:

drivers/crypto/marvell/tdma.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,14 @@ void mv_cesa_tdma_chain(struct mv_cesa_engine *engine,
109109
last->next = dreq->chain.first;
110110
engine->chain.last = dreq->chain.last;
111111

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))
113120
last->next_dma = dreq->chain.first->cur_dma;
114121
}
115122
}

0 commit comments

Comments
 (0)