Mention branches and keyring.
[releases.git] / marvell / cesa / hash.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Hash algorithms supported by the CESA: MD5, SHA1 and SHA256.
4  *
5  * Author: Boris Brezillon <boris.brezillon@free-electrons.com>
6  * Author: Arnaud Ebalard <arno@natisbad.org>
7  *
8  * This work is based on an initial version written by
9  * Sebastian Andrzej Siewior < sebastian at breakpoint dot cc >
10  */
11
12 #include <crypto/hmac.h>
13 #include <crypto/md5.h>
14 #include <crypto/sha1.h>
15 #include <crypto/sha2.h>
16 #include <linux/device.h>
17 #include <linux/dma-mapping.h>
18
19 #include "cesa.h"
20
21 struct mv_cesa_ahash_dma_iter {
22         struct mv_cesa_dma_iter base;
23         struct mv_cesa_sg_dma_iter src;
24 };
25
26 static inline void
27 mv_cesa_ahash_req_iter_init(struct mv_cesa_ahash_dma_iter *iter,
28                             struct ahash_request *req)
29 {
30         struct mv_cesa_ahash_req *creq = ahash_request_ctx(req);
31         unsigned int len = req->nbytes + creq->cache_ptr;
32
33         if (!creq->last_req)
34                 len &= ~CESA_HASH_BLOCK_SIZE_MSK;
35
36         mv_cesa_req_dma_iter_init(&iter->base, len);
37         mv_cesa_sg_dma_iter_init(&iter->src, req->src, DMA_TO_DEVICE);
38         iter->src.op_offset = creq->cache_ptr;
39 }
40
41 static inline bool
42 mv_cesa_ahash_req_iter_next_op(struct mv_cesa_ahash_dma_iter *iter)
43 {
44         iter->src.op_offset = 0;
45
46         return mv_cesa_req_dma_iter_next_op(&iter->base);
47 }
48
49 static inline int
50 mv_cesa_ahash_dma_alloc_cache(struct mv_cesa_ahash_dma_req *req, gfp_t flags)
51 {
52         req->cache = dma_pool_alloc(cesa_dev->dma->cache_pool, flags,
53                                     &req->cache_dma);
54         if (!req->cache)
55                 return -ENOMEM;
56
57         return 0;
58 }
59
60 static inline void
61 mv_cesa_ahash_dma_free_cache(struct mv_cesa_ahash_dma_req *req)
62 {
63         if (!req->cache)
64                 return;
65
66         dma_pool_free(cesa_dev->dma->cache_pool, req->cache,
67                       req->cache_dma);
68 }
69
70 static int mv_cesa_ahash_dma_alloc_padding(struct mv_cesa_ahash_dma_req *req,
71                                            gfp_t flags)
72 {
73         if (req->padding)
74                 return 0;
75
76         req->padding = dma_pool_alloc(cesa_dev->dma->padding_pool, flags,
77                                       &req->padding_dma);
78         if (!req->padding)
79                 return -ENOMEM;
80
81         return 0;
82 }
83
84 static void mv_cesa_ahash_dma_free_padding(struct mv_cesa_ahash_dma_req *req)
85 {
86         if (!req->padding)
87                 return;
88
89         dma_pool_free(cesa_dev->dma->padding_pool, req->padding,
90                       req->padding_dma);
91         req->padding = NULL;
92 }
93
94 static inline void mv_cesa_ahash_dma_last_cleanup(struct ahash_request *req)
95 {
96         struct mv_cesa_ahash_req *creq = ahash_request_ctx(req);
97
98         mv_cesa_ahash_dma_free_padding(&creq->req.dma);
99 }
100
101 static inline void mv_cesa_ahash_dma_cleanup(struct ahash_request *req)
102 {
103         struct mv_cesa_ahash_req *creq = ahash_request_ctx(req);
104
105         dma_unmap_sg(cesa_dev->dev, req->src, creq->src_nents, DMA_TO_DEVICE);
106         mv_cesa_ahash_dma_free_cache(&creq->req.dma);
107         mv_cesa_dma_cleanup(&creq->base);
108 }
109
110 static inline void mv_cesa_ahash_cleanup(struct ahash_request *req)
111 {
112         struct mv_cesa_ahash_req *creq = ahash_request_ctx(req);
113
114         if (mv_cesa_req_get_type(&creq->base) == CESA_DMA_REQ)
115                 mv_cesa_ahash_dma_cleanup(req);
116 }
117
118 static void mv_cesa_ahash_last_cleanup(struct ahash_request *req)
119 {
120         struct mv_cesa_ahash_req *creq = ahash_request_ctx(req);
121
122         if (mv_cesa_req_get_type(&creq->base) == CESA_DMA_REQ)
123                 mv_cesa_ahash_dma_last_cleanup(req);
124 }
125
126 static int mv_cesa_ahash_pad_len(struct mv_cesa_ahash_req *creq)
127 {
128         unsigned int index, padlen;
129
130         index = creq->len & CESA_HASH_BLOCK_SIZE_MSK;
131         padlen = (index < 56) ? (56 - index) : (64 + 56 - index);
132
133         return padlen;
134 }
135
136 static int mv_cesa_ahash_pad_req(struct mv_cesa_ahash_req *creq, u8 *buf)
137 {
138         unsigned int padlen;
139
140         buf[0] = 0x80;
141         /* Pad out to 56 mod 64 */
142         padlen = mv_cesa_ahash_pad_len(creq);
143         memset(buf + 1, 0, padlen - 1);
144
145         if (creq->algo_le) {
146                 __le64 bits = cpu_to_le64(creq->len << 3);
147
148                 memcpy(buf + padlen, &bits, sizeof(bits));
149         } else {
150                 __be64 bits = cpu_to_be64(creq->len << 3);
151
152                 memcpy(buf + padlen, &bits, sizeof(bits));
153         }
154
155         return padlen + 8;
156 }
157
158 static void mv_cesa_ahash_std_step(struct ahash_request *req)
159 {
160         struct mv_cesa_ahash_req *creq = ahash_request_ctx(req);
161         struct mv_cesa_ahash_std_req *sreq = &creq->req.std;
162         struct mv_cesa_engine *engine = creq->base.engine;
163         struct mv_cesa_op_ctx *op;
164         unsigned int new_cache_ptr = 0;
165         u32 frag_mode;
166         size_t  len;
167         unsigned int digsize;
168         int i;
169
170         mv_cesa_adjust_op(engine, &creq->op_tmpl);
171         if (engine->pool)
172                 memcpy(engine->sram_pool, &creq->op_tmpl,
173                        sizeof(creq->op_tmpl));
174         else
175                 memcpy_toio(engine->sram, &creq->op_tmpl,
176                             sizeof(creq->op_tmpl));
177
178         if (!sreq->offset) {
179                 digsize = crypto_ahash_digestsize(crypto_ahash_reqtfm(req));
180                 for (i = 0; i < digsize / 4; i++)
181                         writel_relaxed(creq->state[i],
182                                        engine->regs + CESA_IVDIG(i));
183         }
184
185         if (creq->cache_ptr) {
186                 if (engine->pool)
187                         memcpy(engine->sram_pool + CESA_SA_DATA_SRAM_OFFSET,
188                                creq->cache, creq->cache_ptr);
189                 else
190                         memcpy_toio(engine->sram + CESA_SA_DATA_SRAM_OFFSET,
191                                     creq->cache, creq->cache_ptr);
192         }
193
194         len = min_t(size_t, req->nbytes + creq->cache_ptr - sreq->offset,
195                     CESA_SA_SRAM_PAYLOAD_SIZE);
196
197         if (!creq->last_req) {
198                 new_cache_ptr = len & CESA_HASH_BLOCK_SIZE_MSK;
199                 len &= ~CESA_HASH_BLOCK_SIZE_MSK;
200         }
201
202         if (len - creq->cache_ptr)
203                 sreq->offset += mv_cesa_sg_copy_to_sram(
204                         engine, req->src, creq->src_nents,
205                         CESA_SA_DATA_SRAM_OFFSET + creq->cache_ptr,
206                         len - creq->cache_ptr, sreq->offset);
207
208         op = &creq->op_tmpl;
209
210         frag_mode = mv_cesa_get_op_cfg(op) & CESA_SA_DESC_CFG_FRAG_MSK;
211
212         if (creq->last_req && sreq->offset == req->nbytes &&
213             creq->len <= CESA_SA_DESC_MAC_SRC_TOTAL_LEN_MAX) {
214                 if (frag_mode == CESA_SA_DESC_CFG_FIRST_FRAG)
215                         frag_mode = CESA_SA_DESC_CFG_NOT_FRAG;
216                 else if (frag_mode == CESA_SA_DESC_CFG_MID_FRAG)
217                         frag_mode = CESA_SA_DESC_CFG_LAST_FRAG;
218         }
219
220         if (frag_mode == CESA_SA_DESC_CFG_NOT_FRAG ||
221             frag_mode == CESA_SA_DESC_CFG_LAST_FRAG) {
222                 if (len &&
223                     creq->len <= CESA_SA_DESC_MAC_SRC_TOTAL_LEN_MAX) {
224                         mv_cesa_set_mac_op_total_len(op, creq->len);
225                 } else {
226                         int trailerlen = mv_cesa_ahash_pad_len(creq) + 8;
227
228                         if (len + trailerlen > CESA_SA_SRAM_PAYLOAD_SIZE) {
229                                 len &= CESA_HASH_BLOCK_SIZE_MSK;
230                                 new_cache_ptr = 64 - trailerlen;
231                                 if (engine->pool)
232                                         memcpy(creq->cache,
233                                                engine->sram_pool +
234                                                CESA_SA_DATA_SRAM_OFFSET + len,
235                                                new_cache_ptr);
236                                 else
237                                         memcpy_fromio(creq->cache,
238                                                       engine->sram +
239                                                       CESA_SA_DATA_SRAM_OFFSET +
240                                                       len,
241                                                       new_cache_ptr);
242                         } else {
243                                 i = mv_cesa_ahash_pad_req(creq, creq->cache);
244                                 len += i;
245                                 if (engine->pool)
246                                         memcpy(engine->sram_pool + len +
247                                                CESA_SA_DATA_SRAM_OFFSET,
248                                                creq->cache, i);
249                                 else
250                                         memcpy_toio(engine->sram + len +
251                                                     CESA_SA_DATA_SRAM_OFFSET,
252                                                     creq->cache, i);
253                         }
254
255                         if (frag_mode == CESA_SA_DESC_CFG_LAST_FRAG)
256                                 frag_mode = CESA_SA_DESC_CFG_MID_FRAG;
257                         else
258                                 frag_mode = CESA_SA_DESC_CFG_FIRST_FRAG;
259                 }
260         }
261
262         mv_cesa_set_mac_op_frag_len(op, len);
263         mv_cesa_update_op_cfg(op, frag_mode, CESA_SA_DESC_CFG_FRAG_MSK);
264
265         /* FIXME: only update enc_len field */
266         if (engine->pool)
267                 memcpy(engine->sram_pool, op, sizeof(*op));
268         else
269                 memcpy_toio(engine->sram, op, sizeof(*op));
270
271         if (frag_mode == CESA_SA_DESC_CFG_FIRST_FRAG)
272                 mv_cesa_update_op_cfg(op, CESA_SA_DESC_CFG_MID_FRAG,
273                                       CESA_SA_DESC_CFG_FRAG_MSK);
274
275         creq->cache_ptr = new_cache_ptr;
276
277         mv_cesa_set_int_mask(engine, CESA_SA_INT_ACCEL0_DONE);
278         writel_relaxed(CESA_SA_CFG_PARA_DIS, engine->regs + CESA_SA_CFG);
279         WARN_ON(readl(engine->regs + CESA_SA_CMD) &
280                 CESA_SA_CMD_EN_CESA_SA_ACCL0);
281         writel(CESA_SA_CMD_EN_CESA_SA_ACCL0, engine->regs + CESA_SA_CMD);
282 }
283
284 static int mv_cesa_ahash_std_process(struct ahash_request *req, u32 status)
285 {
286         struct mv_cesa_ahash_req *creq = ahash_request_ctx(req);
287         struct mv_cesa_ahash_std_req *sreq = &creq->req.std;
288
289         if (sreq->offset < (req->nbytes - creq->cache_ptr))
290                 return -EINPROGRESS;
291
292         return 0;
293 }
294
295 static inline void mv_cesa_ahash_dma_prepare(struct ahash_request *req)
296 {
297         struct mv_cesa_ahash_req *creq = ahash_request_ctx(req);
298         struct mv_cesa_req *basereq = &creq->base;
299
300         mv_cesa_dma_prepare(basereq, basereq->engine);
301 }
302
303 static void mv_cesa_ahash_std_prepare(struct ahash_request *req)
304 {
305         struct mv_cesa_ahash_req *creq = ahash_request_ctx(req);
306         struct mv_cesa_ahash_std_req *sreq = &creq->req.std;
307
308         sreq->offset = 0;
309 }
310
311 static void mv_cesa_ahash_dma_step(struct ahash_request *req)
312 {
313         struct mv_cesa_ahash_req *creq = ahash_request_ctx(req);
314         struct mv_cesa_req *base = &creq->base;
315
316         /* We must explicitly set the digest state. */
317         if (base->chain.first->flags & CESA_TDMA_SET_STATE) {
318                 struct mv_cesa_engine *engine = base->engine;
319                 int i;
320
321                 /* Set the hash state in the IVDIG regs. */
322                 for (i = 0; i < ARRAY_SIZE(creq->state); i++)
323                         writel_relaxed(creq->state[i], engine->regs +
324                                        CESA_IVDIG(i));
325         }
326
327         mv_cesa_dma_step(base);
328 }
329
330 static void mv_cesa_ahash_step(struct crypto_async_request *req)
331 {
332         struct ahash_request *ahashreq = ahash_request_cast(req);
333         struct mv_cesa_ahash_req *creq = ahash_request_ctx(ahashreq);
334
335         if (mv_cesa_req_get_type(&creq->base) == CESA_DMA_REQ)
336                 mv_cesa_ahash_dma_step(ahashreq);
337         else
338                 mv_cesa_ahash_std_step(ahashreq);
339 }
340
341 static int mv_cesa_ahash_process(struct crypto_async_request *req, u32 status)
342 {
343         struct ahash_request *ahashreq = ahash_request_cast(req);
344         struct mv_cesa_ahash_req *creq = ahash_request_ctx(ahashreq);
345
346         if (mv_cesa_req_get_type(&creq->base) == CESA_DMA_REQ)
347                 return mv_cesa_dma_process(&creq->base, status);
348
349         return mv_cesa_ahash_std_process(ahashreq, status);
350 }
351
352 static void mv_cesa_ahash_complete(struct crypto_async_request *req)
353 {
354         struct ahash_request *ahashreq = ahash_request_cast(req);
355         struct mv_cesa_ahash_req *creq = ahash_request_ctx(ahashreq);
356         struct mv_cesa_engine *engine = creq->base.engine;
357         unsigned int digsize;
358         int i;
359
360         digsize = crypto_ahash_digestsize(crypto_ahash_reqtfm(ahashreq));
361
362         if (mv_cesa_req_get_type(&creq->base) == CESA_DMA_REQ &&
363             (creq->base.chain.last->flags & CESA_TDMA_TYPE_MSK) ==
364              CESA_TDMA_RESULT) {
365                 __le32 *data = NULL;
366
367                 /*
368                  * Result is already in the correct endianness when the SA is
369                  * used
370                  */
371                 data = creq->base.chain.last->op->ctx.hash.hash;
372                 for (i = 0; i < digsize / 4; i++)
373                         creq->state[i] = le32_to_cpu(data[i]);
374
375                 memcpy(ahashreq->result, data, digsize);
376         } else {
377                 for (i = 0; i < digsize / 4; i++)
378                         creq->state[i] = readl_relaxed(engine->regs +
379                                                        CESA_IVDIG(i));
380                 if (creq->last_req) {
381                         /*
382                          * Hardware's MD5 digest is in little endian format, but
383                          * SHA in big endian format
384                          */
385                         if (creq->algo_le) {
386                                 __le32 *result = (void *)ahashreq->result;
387
388                                 for (i = 0; i < digsize / 4; i++)
389                                         result[i] = cpu_to_le32(creq->state[i]);
390                         } else {
391                                 __be32 *result = (void *)ahashreq->result;
392
393                                 for (i = 0; i < digsize / 4; i++)
394                                         result[i] = cpu_to_be32(creq->state[i]);
395                         }
396                 }
397         }
398
399         atomic_sub(ahashreq->nbytes, &engine->load);
400 }
401
402 static void mv_cesa_ahash_prepare(struct crypto_async_request *req,
403                                   struct mv_cesa_engine *engine)
404 {
405         struct ahash_request *ahashreq = ahash_request_cast(req);
406         struct mv_cesa_ahash_req *creq = ahash_request_ctx(ahashreq);
407
408         creq->base.engine = engine;
409
410         if (mv_cesa_req_get_type(&creq->base) == CESA_DMA_REQ)
411                 mv_cesa_ahash_dma_prepare(ahashreq);
412         else
413                 mv_cesa_ahash_std_prepare(ahashreq);
414 }
415
416 static void mv_cesa_ahash_req_cleanup(struct crypto_async_request *req)
417 {
418         struct ahash_request *ahashreq = ahash_request_cast(req);
419         struct mv_cesa_ahash_req *creq = ahash_request_ctx(ahashreq);
420
421         if (creq->last_req)
422                 mv_cesa_ahash_last_cleanup(ahashreq);
423
424         mv_cesa_ahash_cleanup(ahashreq);
425
426         if (creq->cache_ptr)
427                 sg_pcopy_to_buffer(ahashreq->src, creq->src_nents,
428                                    creq->cache,
429                                    creq->cache_ptr,
430                                    ahashreq->nbytes - creq->cache_ptr);
431 }
432
433 static const struct mv_cesa_req_ops mv_cesa_ahash_req_ops = {
434         .step = mv_cesa_ahash_step,
435         .process = mv_cesa_ahash_process,
436         .cleanup = mv_cesa_ahash_req_cleanup,
437         .complete = mv_cesa_ahash_complete,
438 };
439
440 static void mv_cesa_ahash_init(struct ahash_request *req,
441                               struct mv_cesa_op_ctx *tmpl, bool algo_le)
442 {
443         struct mv_cesa_ahash_req *creq = ahash_request_ctx(req);
444
445         memset(creq, 0, sizeof(*creq));
446         mv_cesa_update_op_cfg(tmpl,
447                               CESA_SA_DESC_CFG_OP_MAC_ONLY |
448                               CESA_SA_DESC_CFG_FIRST_FRAG,
449                               CESA_SA_DESC_CFG_OP_MSK |
450                               CESA_SA_DESC_CFG_FRAG_MSK);
451         mv_cesa_set_mac_op_total_len(tmpl, 0);
452         mv_cesa_set_mac_op_frag_len(tmpl, 0);
453         creq->op_tmpl = *tmpl;
454         creq->len = 0;
455         creq->algo_le = algo_le;
456 }
457
458 static inline int mv_cesa_ahash_cra_init(struct crypto_tfm *tfm)
459 {
460         struct mv_cesa_hash_ctx *ctx = crypto_tfm_ctx(tfm);
461
462         ctx->base.ops = &mv_cesa_ahash_req_ops;
463
464         crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
465                                  sizeof(struct mv_cesa_ahash_req));
466         return 0;
467 }
468
469 static bool mv_cesa_ahash_cache_req(struct ahash_request *req)
470 {
471         struct mv_cesa_ahash_req *creq = ahash_request_ctx(req);
472         bool cached = false;
473
474         if (creq->cache_ptr + req->nbytes < CESA_MAX_HASH_BLOCK_SIZE &&
475             !creq->last_req) {
476                 cached = true;
477
478                 if (!req->nbytes)
479                         return cached;
480
481                 sg_pcopy_to_buffer(req->src, creq->src_nents,
482                                    creq->cache + creq->cache_ptr,
483                                    req->nbytes, 0);
484
485                 creq->cache_ptr += req->nbytes;
486         }
487
488         return cached;
489 }
490
491 static struct mv_cesa_op_ctx *
492 mv_cesa_dma_add_frag(struct mv_cesa_tdma_chain *chain,
493                      struct mv_cesa_op_ctx *tmpl, unsigned int frag_len,
494                      gfp_t flags)
495 {
496         struct mv_cesa_op_ctx *op;
497         int ret;
498
499         op = mv_cesa_dma_add_op(chain, tmpl, false, flags);
500         if (IS_ERR(op))
501                 return op;
502
503         /* Set the operation block fragment length. */
504         mv_cesa_set_mac_op_frag_len(op, frag_len);
505
506         /* Append dummy desc to launch operation */
507         ret = mv_cesa_dma_add_dummy_launch(chain, flags);
508         if (ret)
509                 return ERR_PTR(ret);
510
511         if (mv_cesa_mac_op_is_first_frag(tmpl))
512                 mv_cesa_update_op_cfg(tmpl,
513                                       CESA_SA_DESC_CFG_MID_FRAG,
514                                       CESA_SA_DESC_CFG_FRAG_MSK);
515
516         return op;
517 }
518
519 static int
520 mv_cesa_ahash_dma_add_cache(struct mv_cesa_tdma_chain *chain,
521                             struct mv_cesa_ahash_req *creq,
522                             gfp_t flags)
523 {
524         struct mv_cesa_ahash_dma_req *ahashdreq = &creq->req.dma;
525         int ret;
526
527         if (!creq->cache_ptr)
528                 return 0;
529
530         ret = mv_cesa_ahash_dma_alloc_cache(ahashdreq, flags);
531         if (ret)
532                 return ret;
533
534         memcpy(ahashdreq->cache, creq->cache, creq->cache_ptr);
535
536         return mv_cesa_dma_add_data_transfer(chain,
537                                              CESA_SA_DATA_SRAM_OFFSET,
538                                              ahashdreq->cache_dma,
539                                              creq->cache_ptr,
540                                              CESA_TDMA_DST_IN_SRAM,
541                                              flags);
542 }
543
544 static struct mv_cesa_op_ctx *
545 mv_cesa_ahash_dma_last_req(struct mv_cesa_tdma_chain *chain,
546                            struct mv_cesa_ahash_dma_iter *dma_iter,
547                            struct mv_cesa_ahash_req *creq,
548                            unsigned int frag_len, gfp_t flags)
549 {
550         struct mv_cesa_ahash_dma_req *ahashdreq = &creq->req.dma;
551         unsigned int len, trailerlen, padoff = 0;
552         struct mv_cesa_op_ctx *op;
553         int ret;
554
555         /*
556          * If the transfer is smaller than our maximum length, and we have
557          * some data outstanding, we can ask the engine to finish the hash.
558          */
559         if (creq->len <= CESA_SA_DESC_MAC_SRC_TOTAL_LEN_MAX && frag_len) {
560                 op = mv_cesa_dma_add_frag(chain, &creq->op_tmpl, frag_len,
561                                           flags);
562                 if (IS_ERR(op))
563                         return op;
564
565                 mv_cesa_set_mac_op_total_len(op, creq->len);
566                 mv_cesa_update_op_cfg(op, mv_cesa_mac_op_is_first_frag(op) ?
567                                                 CESA_SA_DESC_CFG_NOT_FRAG :
568                                                 CESA_SA_DESC_CFG_LAST_FRAG,
569                                       CESA_SA_DESC_CFG_FRAG_MSK);
570
571                 ret = mv_cesa_dma_add_result_op(chain,
572                                                 CESA_SA_CFG_SRAM_OFFSET,
573                                                 CESA_SA_DATA_SRAM_OFFSET,
574                                                 CESA_TDMA_SRC_IN_SRAM, flags);
575                 if (ret)
576                         return ERR_PTR(-ENOMEM);
577                 return op;
578         }
579
580         /*
581          * The request is longer than the engine can handle, or we have
582          * no data outstanding. Manually generate the padding, adding it
583          * as a "mid" fragment.
584          */
585         ret = mv_cesa_ahash_dma_alloc_padding(ahashdreq, flags);
586         if (ret)
587                 return ERR_PTR(ret);
588
589         trailerlen = mv_cesa_ahash_pad_req(creq, ahashdreq->padding);
590
591         len = min(CESA_SA_SRAM_PAYLOAD_SIZE - frag_len, trailerlen);
592         if (len) {
593                 ret = mv_cesa_dma_add_data_transfer(chain,
594                                                 CESA_SA_DATA_SRAM_OFFSET +
595                                                 frag_len,
596                                                 ahashdreq->padding_dma,
597                                                 len, CESA_TDMA_DST_IN_SRAM,
598                                                 flags);
599                 if (ret)
600                         return ERR_PTR(ret);
601
602                 op = mv_cesa_dma_add_frag(chain, &creq->op_tmpl, frag_len + len,
603                                           flags);
604                 if (IS_ERR(op))
605                         return op;
606
607                 if (len == trailerlen)
608                         return op;
609
610                 padoff += len;
611         }
612
613         ret = mv_cesa_dma_add_data_transfer(chain,
614                                             CESA_SA_DATA_SRAM_OFFSET,
615                                             ahashdreq->padding_dma +
616                                             padoff,
617                                             trailerlen - padoff,
618                                             CESA_TDMA_DST_IN_SRAM,
619                                             flags);
620         if (ret)
621                 return ERR_PTR(ret);
622
623         return mv_cesa_dma_add_frag(chain, &creq->op_tmpl, trailerlen - padoff,
624                                     flags);
625 }
626
627 static int mv_cesa_ahash_dma_req_init(struct ahash_request *req)
628 {
629         struct mv_cesa_ahash_req *creq = ahash_request_ctx(req);
630         gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
631                       GFP_KERNEL : GFP_ATOMIC;
632         struct mv_cesa_req *basereq = &creq->base;
633         struct mv_cesa_ahash_dma_iter iter;
634         struct mv_cesa_op_ctx *op = NULL;
635         unsigned int frag_len;
636         bool set_state = false;
637         int ret;
638         u32 type;
639
640         basereq->chain.first = NULL;
641         basereq->chain.last = NULL;
642
643         if (!mv_cesa_mac_op_is_first_frag(&creq->op_tmpl))
644                 set_state = true;
645
646         if (creq->src_nents) {
647                 ret = dma_map_sg(cesa_dev->dev, req->src, creq->src_nents,
648                                  DMA_TO_DEVICE);
649                 if (!ret) {
650                         ret = -ENOMEM;
651                         goto err;
652                 }
653         }
654
655         mv_cesa_tdma_desc_iter_init(&basereq->chain);
656         mv_cesa_ahash_req_iter_init(&iter, req);
657
658         /*
659          * Add the cache (left-over data from a previous block) first.
660          * This will never overflow the SRAM size.
661          */
662         ret = mv_cesa_ahash_dma_add_cache(&basereq->chain, creq, flags);
663         if (ret)
664                 goto err_free_tdma;
665
666         if (iter.src.sg) {
667                 /*
668                  * Add all the new data, inserting an operation block and
669                  * launch command between each full SRAM block-worth of
670                  * data. We intentionally do not add the final op block.
671                  */
672                 while (true) {
673                         ret = mv_cesa_dma_add_op_transfers(&basereq->chain,
674                                                            &iter.base,
675                                                            &iter.src, flags);
676                         if (ret)
677                                 goto err_free_tdma;
678
679                         frag_len = iter.base.op_len;
680
681                         if (!mv_cesa_ahash_req_iter_next_op(&iter))
682                                 break;
683
684                         op = mv_cesa_dma_add_frag(&basereq->chain,
685                                                   &creq->op_tmpl,
686                                                   frag_len, flags);
687                         if (IS_ERR(op)) {
688                                 ret = PTR_ERR(op);
689                                 goto err_free_tdma;
690                         }
691                 }
692         } else {
693                 /* Account for the data that was in the cache. */
694                 frag_len = iter.base.op_len;
695         }
696
697         /*
698          * At this point, frag_len indicates whether we have any data
699          * outstanding which needs an operation.  Queue up the final
700          * operation, which depends whether this is the final request.
701          */
702         if (creq->last_req)
703                 op = mv_cesa_ahash_dma_last_req(&basereq->chain, &iter, creq,
704                                                 frag_len, flags);
705         else if (frag_len)
706                 op = mv_cesa_dma_add_frag(&basereq->chain, &creq->op_tmpl,
707                                           frag_len, flags);
708
709         if (IS_ERR(op)) {
710                 ret = PTR_ERR(op);
711                 goto err_free_tdma;
712         }
713
714         /*
715          * If results are copied via DMA, this means that this
716          * request can be directly processed by the engine,
717          * without partial updates. So we can chain it at the
718          * DMA level with other requests.
719          */
720         type = basereq->chain.last->flags & CESA_TDMA_TYPE_MSK;
721
722         if (op && type != CESA_TDMA_RESULT) {
723                 /* Add dummy desc to wait for crypto operation end */
724                 ret = mv_cesa_dma_add_dummy_end(&basereq->chain, flags);
725                 if (ret)
726                         goto err_free_tdma;
727         }
728
729         if (!creq->last_req)
730                 creq->cache_ptr = req->nbytes + creq->cache_ptr -
731                                   iter.base.len;
732         else
733                 creq->cache_ptr = 0;
734
735         basereq->chain.last->flags |= CESA_TDMA_END_OF_REQ;
736
737         if (type != CESA_TDMA_RESULT)
738                 basereq->chain.last->flags |= CESA_TDMA_BREAK_CHAIN;
739
740         if (set_state) {
741                 /*
742                  * Put the CESA_TDMA_SET_STATE flag on the first tdma desc to
743                  * let the step logic know that the IVDIG registers should be
744                  * explicitly set before launching a TDMA chain.
745                  */
746                 basereq->chain.first->flags |= CESA_TDMA_SET_STATE;
747         }
748
749         return 0;
750
751 err_free_tdma:
752         mv_cesa_dma_cleanup(basereq);
753         dma_unmap_sg(cesa_dev->dev, req->src, creq->src_nents, DMA_TO_DEVICE);
754
755 err:
756         mv_cesa_ahash_last_cleanup(req);
757
758         return ret;
759 }
760
761 static int mv_cesa_ahash_req_init(struct ahash_request *req, bool *cached)
762 {
763         struct mv_cesa_ahash_req *creq = ahash_request_ctx(req);
764
765         creq->src_nents = sg_nents_for_len(req->src, req->nbytes);
766         if (creq->src_nents < 0) {
767                 dev_err(cesa_dev->dev, "Invalid number of src SG");
768                 return creq->src_nents;
769         }
770
771         *cached = mv_cesa_ahash_cache_req(req);
772
773         if (*cached)
774                 return 0;
775
776         if (cesa_dev->caps->has_tdma)
777                 return mv_cesa_ahash_dma_req_init(req);
778         else
779                 return 0;
780 }
781
782 static int mv_cesa_ahash_queue_req(struct ahash_request *req)
783 {
784         struct mv_cesa_ahash_req *creq = ahash_request_ctx(req);
785         struct mv_cesa_engine *engine;
786         bool cached = false;
787         int ret;
788
789         ret = mv_cesa_ahash_req_init(req, &cached);
790         if (ret)
791                 return ret;
792
793         if (cached)
794                 return 0;
795
796         engine = mv_cesa_select_engine(req->nbytes);
797         mv_cesa_ahash_prepare(&req->base, engine);
798
799         ret = mv_cesa_queue_req(&req->base, &creq->base);
800
801         if (mv_cesa_req_needs_cleanup(&req->base, ret))
802                 mv_cesa_ahash_cleanup(req);
803
804         return ret;
805 }
806
807 static int mv_cesa_ahash_update(struct ahash_request *req)
808 {
809         struct mv_cesa_ahash_req *creq = ahash_request_ctx(req);
810
811         creq->len += req->nbytes;
812
813         return mv_cesa_ahash_queue_req(req);
814 }
815
816 static int mv_cesa_ahash_final(struct ahash_request *req)
817 {
818         struct mv_cesa_ahash_req *creq = ahash_request_ctx(req);
819         struct mv_cesa_op_ctx *tmpl = &creq->op_tmpl;
820
821         mv_cesa_set_mac_op_total_len(tmpl, creq->len);
822         creq->last_req = true;
823         req->nbytes = 0;
824
825         return mv_cesa_ahash_queue_req(req);
826 }
827
828 static int mv_cesa_ahash_finup(struct ahash_request *req)
829 {
830         struct mv_cesa_ahash_req *creq = ahash_request_ctx(req);
831         struct mv_cesa_op_ctx *tmpl = &creq->op_tmpl;
832
833         creq->len += req->nbytes;
834         mv_cesa_set_mac_op_total_len(tmpl, creq->len);
835         creq->last_req = true;
836
837         return mv_cesa_ahash_queue_req(req);
838 }
839
840 static int mv_cesa_ahash_export(struct ahash_request *req, void *hash,
841                                 u64 *len, void *cache)
842 {
843         struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
844         struct mv_cesa_ahash_req *creq = ahash_request_ctx(req);
845         unsigned int digsize = crypto_ahash_digestsize(ahash);
846         unsigned int blocksize;
847
848         blocksize = crypto_ahash_blocksize(ahash);
849
850         *len = creq->len;
851         memcpy(hash, creq->state, digsize);
852         memset(cache, 0, blocksize);
853         memcpy(cache, creq->cache, creq->cache_ptr);
854
855         return 0;
856 }
857
858 static int mv_cesa_ahash_import(struct ahash_request *req, const void *hash,
859                                 u64 len, const void *cache)
860 {
861         struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
862         struct mv_cesa_ahash_req *creq = ahash_request_ctx(req);
863         unsigned int digsize = crypto_ahash_digestsize(ahash);
864         unsigned int blocksize;
865         unsigned int cache_ptr;
866         int ret;
867
868         ret = crypto_ahash_init(req);
869         if (ret)
870                 return ret;
871
872         blocksize = crypto_ahash_blocksize(ahash);
873         if (len >= blocksize)
874                 mv_cesa_update_op_cfg(&creq->op_tmpl,
875                                       CESA_SA_DESC_CFG_MID_FRAG,
876                                       CESA_SA_DESC_CFG_FRAG_MSK);
877
878         creq->len = len;
879         memcpy(creq->state, hash, digsize);
880         creq->cache_ptr = 0;
881
882         cache_ptr = do_div(len, blocksize);
883         if (!cache_ptr)
884                 return 0;
885
886         memcpy(creq->cache, cache, cache_ptr);
887         creq->cache_ptr = cache_ptr;
888
889         return 0;
890 }
891
892 static int mv_cesa_md5_init(struct ahash_request *req)
893 {
894         struct mv_cesa_ahash_req *creq = ahash_request_ctx(req);
895         struct mv_cesa_op_ctx tmpl = { };
896
897         mv_cesa_set_op_cfg(&tmpl, CESA_SA_DESC_CFG_MACM_MD5);
898
899         mv_cesa_ahash_init(req, &tmpl, true);
900
901         creq->state[0] = MD5_H0;
902         creq->state[1] = MD5_H1;
903         creq->state[2] = MD5_H2;
904         creq->state[3] = MD5_H3;
905
906         return 0;
907 }
908
909 static int mv_cesa_md5_export(struct ahash_request *req, void *out)
910 {
911         struct md5_state *out_state = out;
912
913         return mv_cesa_ahash_export(req, out_state->hash,
914                                     &out_state->byte_count, out_state->block);
915 }
916
917 static int mv_cesa_md5_import(struct ahash_request *req, const void *in)
918 {
919         const struct md5_state *in_state = in;
920
921         return mv_cesa_ahash_import(req, in_state->hash, in_state->byte_count,
922                                     in_state->block);
923 }
924
925 static int mv_cesa_md5_digest(struct ahash_request *req)
926 {
927         int ret;
928
929         ret = mv_cesa_md5_init(req);
930         if (ret)
931                 return ret;
932
933         return mv_cesa_ahash_finup(req);
934 }
935
936 struct ahash_alg mv_md5_alg = {
937         .init = mv_cesa_md5_init,
938         .update = mv_cesa_ahash_update,
939         .final = mv_cesa_ahash_final,
940         .finup = mv_cesa_ahash_finup,
941         .digest = mv_cesa_md5_digest,
942         .export = mv_cesa_md5_export,
943         .import = mv_cesa_md5_import,
944         .halg = {
945                 .digestsize = MD5_DIGEST_SIZE,
946                 .statesize = sizeof(struct md5_state),
947                 .base = {
948                         .cra_name = "md5",
949                         .cra_driver_name = "mv-md5",
950                         .cra_priority = 300,
951                         .cra_flags = CRYPTO_ALG_ASYNC |
952                                      CRYPTO_ALG_ALLOCATES_MEMORY |
953                                      CRYPTO_ALG_KERN_DRIVER_ONLY,
954                         .cra_blocksize = MD5_HMAC_BLOCK_SIZE,
955                         .cra_ctxsize = sizeof(struct mv_cesa_hash_ctx),
956                         .cra_init = mv_cesa_ahash_cra_init,
957                         .cra_module = THIS_MODULE,
958                 }
959         }
960 };
961
962 static int mv_cesa_sha1_init(struct ahash_request *req)
963 {
964         struct mv_cesa_ahash_req *creq = ahash_request_ctx(req);
965         struct mv_cesa_op_ctx tmpl = { };
966
967         mv_cesa_set_op_cfg(&tmpl, CESA_SA_DESC_CFG_MACM_SHA1);
968
969         mv_cesa_ahash_init(req, &tmpl, false);
970
971         creq->state[0] = SHA1_H0;
972         creq->state[1] = SHA1_H1;
973         creq->state[2] = SHA1_H2;
974         creq->state[3] = SHA1_H3;
975         creq->state[4] = SHA1_H4;
976
977         return 0;
978 }
979
980 static int mv_cesa_sha1_export(struct ahash_request *req, void *out)
981 {
982         struct sha1_state *out_state = out;
983
984         return mv_cesa_ahash_export(req, out_state->state, &out_state->count,
985                                     out_state->buffer);
986 }
987
988 static int mv_cesa_sha1_import(struct ahash_request *req, const void *in)
989 {
990         const struct sha1_state *in_state = in;
991
992         return mv_cesa_ahash_import(req, in_state->state, in_state->count,
993                                     in_state->buffer);
994 }
995
996 static int mv_cesa_sha1_digest(struct ahash_request *req)
997 {
998         int ret;
999
1000         ret = mv_cesa_sha1_init(req);
1001         if (ret)
1002                 return ret;
1003
1004         return mv_cesa_ahash_finup(req);
1005 }
1006
1007 struct ahash_alg mv_sha1_alg = {
1008         .init = mv_cesa_sha1_init,
1009         .update = mv_cesa_ahash_update,
1010         .final = mv_cesa_ahash_final,
1011         .finup = mv_cesa_ahash_finup,
1012         .digest = mv_cesa_sha1_digest,
1013         .export = mv_cesa_sha1_export,
1014         .import = mv_cesa_sha1_import,
1015         .halg = {
1016                 .digestsize = SHA1_DIGEST_SIZE,
1017                 .statesize = sizeof(struct sha1_state),
1018                 .base = {
1019                         .cra_name = "sha1",
1020                         .cra_driver_name = "mv-sha1",
1021                         .cra_priority = 300,
1022                         .cra_flags = CRYPTO_ALG_ASYNC |
1023                                      CRYPTO_ALG_ALLOCATES_MEMORY |
1024                                      CRYPTO_ALG_KERN_DRIVER_ONLY,
1025                         .cra_blocksize = SHA1_BLOCK_SIZE,
1026                         .cra_ctxsize = sizeof(struct mv_cesa_hash_ctx),
1027                         .cra_init = mv_cesa_ahash_cra_init,
1028                         .cra_module = THIS_MODULE,
1029                 }
1030         }
1031 };
1032
1033 static int mv_cesa_sha256_init(struct ahash_request *req)
1034 {
1035         struct mv_cesa_ahash_req *creq = ahash_request_ctx(req);
1036         struct mv_cesa_op_ctx tmpl = { };
1037
1038         mv_cesa_set_op_cfg(&tmpl, CESA_SA_DESC_CFG_MACM_SHA256);
1039
1040         mv_cesa_ahash_init(req, &tmpl, false);
1041
1042         creq->state[0] = SHA256_H0;
1043         creq->state[1] = SHA256_H1;
1044         creq->state[2] = SHA256_H2;
1045         creq->state[3] = SHA256_H3;
1046         creq->state[4] = SHA256_H4;
1047         creq->state[5] = SHA256_H5;
1048         creq->state[6] = SHA256_H6;
1049         creq->state[7] = SHA256_H7;
1050
1051         return 0;
1052 }
1053
1054 static int mv_cesa_sha256_digest(struct ahash_request *req)
1055 {
1056         int ret;
1057
1058         ret = mv_cesa_sha256_init(req);
1059         if (ret)
1060                 return ret;
1061
1062         return mv_cesa_ahash_finup(req);
1063 }
1064
1065 static int mv_cesa_sha256_export(struct ahash_request *req, void *out)
1066 {
1067         struct sha256_state *out_state = out;
1068
1069         return mv_cesa_ahash_export(req, out_state->state, &out_state->count,
1070                                     out_state->buf);
1071 }
1072
1073 static int mv_cesa_sha256_import(struct ahash_request *req, const void *in)
1074 {
1075         const struct sha256_state *in_state = in;
1076
1077         return mv_cesa_ahash_import(req, in_state->state, in_state->count,
1078                                     in_state->buf);
1079 }
1080
1081 struct ahash_alg mv_sha256_alg = {
1082         .init = mv_cesa_sha256_init,
1083         .update = mv_cesa_ahash_update,
1084         .final = mv_cesa_ahash_final,
1085         .finup = mv_cesa_ahash_finup,
1086         .digest = mv_cesa_sha256_digest,
1087         .export = mv_cesa_sha256_export,
1088         .import = mv_cesa_sha256_import,
1089         .halg = {
1090                 .digestsize = SHA256_DIGEST_SIZE,
1091                 .statesize = sizeof(struct sha256_state),
1092                 .base = {
1093                         .cra_name = "sha256",
1094                         .cra_driver_name = "mv-sha256",
1095                         .cra_priority = 300,
1096                         .cra_flags = CRYPTO_ALG_ASYNC |
1097                                      CRYPTO_ALG_ALLOCATES_MEMORY |
1098                                      CRYPTO_ALG_KERN_DRIVER_ONLY,
1099                         .cra_blocksize = SHA256_BLOCK_SIZE,
1100                         .cra_ctxsize = sizeof(struct mv_cesa_hash_ctx),
1101                         .cra_init = mv_cesa_ahash_cra_init,
1102                         .cra_module = THIS_MODULE,
1103                 }
1104         }
1105 };
1106
1107 struct mv_cesa_ahash_result {
1108         struct completion completion;
1109         int error;
1110 };
1111
1112 static void mv_cesa_hmac_ahash_complete(struct crypto_async_request *req,
1113                                         int error)
1114 {
1115         struct mv_cesa_ahash_result *result = req->data;
1116
1117         if (error == -EINPROGRESS)
1118                 return;
1119
1120         result->error = error;
1121         complete(&result->completion);
1122 }
1123
1124 static int mv_cesa_ahmac_iv_state_init(struct ahash_request *req, u8 *pad,
1125                                        void *state, unsigned int blocksize)
1126 {
1127         struct mv_cesa_ahash_result result;
1128         struct scatterlist sg;
1129         int ret;
1130
1131         ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
1132                                    mv_cesa_hmac_ahash_complete, &result);
1133         sg_init_one(&sg, pad, blocksize);
1134         ahash_request_set_crypt(req, &sg, pad, blocksize);
1135         init_completion(&result.completion);
1136
1137         ret = crypto_ahash_init(req);
1138         if (ret)
1139                 return ret;
1140
1141         ret = crypto_ahash_update(req);
1142         if (ret && ret != -EINPROGRESS)
1143                 return ret;
1144
1145         wait_for_completion_interruptible(&result.completion);
1146         if (result.error)
1147                 return result.error;
1148
1149         ret = crypto_ahash_export(req, state);
1150         if (ret)
1151                 return ret;
1152
1153         return 0;
1154 }
1155
1156 static int mv_cesa_ahmac_pad_init(struct ahash_request *req,
1157                                   const u8 *key, unsigned int keylen,
1158                                   u8 *ipad, u8 *opad,
1159                                   unsigned int blocksize)
1160 {
1161         struct mv_cesa_ahash_result result;
1162         struct scatterlist sg;
1163         int ret;
1164         int i;
1165
1166         if (keylen <= blocksize) {
1167                 memcpy(ipad, key, keylen);
1168         } else {
1169                 u8 *keydup = kmemdup(key, keylen, GFP_KERNEL);
1170
1171                 if (!keydup)
1172                         return -ENOMEM;
1173
1174                 ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
1175                                            mv_cesa_hmac_ahash_complete,
1176                                            &result);
1177                 sg_init_one(&sg, keydup, keylen);
1178                 ahash_request_set_crypt(req, &sg, ipad, keylen);
1179                 init_completion(&result.completion);
1180
1181                 ret = crypto_ahash_digest(req);
1182                 if (ret == -EINPROGRESS) {
1183                         wait_for_completion_interruptible(&result.completion);
1184                         ret = result.error;
1185                 }
1186
1187                 /* Set the memory region to 0 to avoid any leak. */
1188                 kfree_sensitive(keydup);
1189
1190                 if (ret)
1191                         return ret;
1192
1193                 keylen = crypto_ahash_digestsize(crypto_ahash_reqtfm(req));
1194         }
1195
1196         memset(ipad + keylen, 0, blocksize - keylen);
1197         memcpy(opad, ipad, blocksize);
1198
1199         for (i = 0; i < blocksize; i++) {
1200                 ipad[i] ^= HMAC_IPAD_VALUE;
1201                 opad[i] ^= HMAC_OPAD_VALUE;
1202         }
1203
1204         return 0;
1205 }
1206
1207 static int mv_cesa_ahmac_setkey(const char *hash_alg_name,
1208                                 const u8 *key, unsigned int keylen,
1209                                 void *istate, void *ostate)
1210 {
1211         struct ahash_request *req;
1212         struct crypto_ahash *tfm;
1213         unsigned int blocksize;
1214         u8 *ipad = NULL;
1215         u8 *opad;
1216         int ret;
1217
1218         tfm = crypto_alloc_ahash(hash_alg_name, 0, 0);
1219         if (IS_ERR(tfm))
1220                 return PTR_ERR(tfm);
1221
1222         req = ahash_request_alloc(tfm, GFP_KERNEL);
1223         if (!req) {
1224                 ret = -ENOMEM;
1225                 goto free_ahash;
1226         }
1227
1228         crypto_ahash_clear_flags(tfm, ~0);
1229
1230         blocksize = crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
1231
1232         ipad = kcalloc(2, blocksize, GFP_KERNEL);
1233         if (!ipad) {
1234                 ret = -ENOMEM;
1235                 goto free_req;
1236         }
1237
1238         opad = ipad + blocksize;
1239
1240         ret = mv_cesa_ahmac_pad_init(req, key, keylen, ipad, opad, blocksize);
1241         if (ret)
1242                 goto free_ipad;
1243
1244         ret = mv_cesa_ahmac_iv_state_init(req, ipad, istate, blocksize);
1245         if (ret)
1246                 goto free_ipad;
1247
1248         ret = mv_cesa_ahmac_iv_state_init(req, opad, ostate, blocksize);
1249
1250 free_ipad:
1251         kfree(ipad);
1252 free_req:
1253         ahash_request_free(req);
1254 free_ahash:
1255         crypto_free_ahash(tfm);
1256
1257         return ret;
1258 }
1259
1260 static int mv_cesa_ahmac_cra_init(struct crypto_tfm *tfm)
1261 {
1262         struct mv_cesa_hmac_ctx *ctx = crypto_tfm_ctx(tfm);
1263
1264         ctx->base.ops = &mv_cesa_ahash_req_ops;
1265
1266         crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
1267                                  sizeof(struct mv_cesa_ahash_req));
1268         return 0;
1269 }
1270
1271 static int mv_cesa_ahmac_md5_init(struct ahash_request *req)
1272 {
1273         struct mv_cesa_hmac_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
1274         struct mv_cesa_op_ctx tmpl = { };
1275
1276         mv_cesa_set_op_cfg(&tmpl, CESA_SA_DESC_CFG_MACM_HMAC_MD5);
1277         memcpy(tmpl.ctx.hash.iv, ctx->iv, sizeof(ctx->iv));
1278
1279         mv_cesa_ahash_init(req, &tmpl, true);
1280
1281         return 0;
1282 }
1283
1284 static int mv_cesa_ahmac_md5_setkey(struct crypto_ahash *tfm, const u8 *key,
1285                                     unsigned int keylen)
1286 {
1287         struct mv_cesa_hmac_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
1288         struct md5_state istate, ostate;
1289         int ret, i;
1290
1291         ret = mv_cesa_ahmac_setkey("mv-md5", key, keylen, &istate, &ostate);
1292         if (ret)
1293                 return ret;
1294
1295         for (i = 0; i < ARRAY_SIZE(istate.hash); i++)
1296                 ctx->iv[i] = cpu_to_be32(istate.hash[i]);
1297
1298         for (i = 0; i < ARRAY_SIZE(ostate.hash); i++)
1299                 ctx->iv[i + 8] = cpu_to_be32(ostate.hash[i]);
1300
1301         return 0;
1302 }
1303
1304 static int mv_cesa_ahmac_md5_digest(struct ahash_request *req)
1305 {
1306         int ret;
1307
1308         ret = mv_cesa_ahmac_md5_init(req);
1309         if (ret)
1310                 return ret;
1311
1312         return mv_cesa_ahash_finup(req);
1313 }
1314
1315 struct ahash_alg mv_ahmac_md5_alg = {
1316         .init = mv_cesa_ahmac_md5_init,
1317         .update = mv_cesa_ahash_update,
1318         .final = mv_cesa_ahash_final,
1319         .finup = mv_cesa_ahash_finup,
1320         .digest = mv_cesa_ahmac_md5_digest,
1321         .setkey = mv_cesa_ahmac_md5_setkey,
1322         .export = mv_cesa_md5_export,
1323         .import = mv_cesa_md5_import,
1324         .halg = {
1325                 .digestsize = MD5_DIGEST_SIZE,
1326                 .statesize = sizeof(struct md5_state),
1327                 .base = {
1328                         .cra_name = "hmac(md5)",
1329                         .cra_driver_name = "mv-hmac-md5",
1330                         .cra_priority = 300,
1331                         .cra_flags = CRYPTO_ALG_ASYNC |
1332                                      CRYPTO_ALG_ALLOCATES_MEMORY |
1333                                      CRYPTO_ALG_KERN_DRIVER_ONLY,
1334                         .cra_blocksize = MD5_HMAC_BLOCK_SIZE,
1335                         .cra_ctxsize = sizeof(struct mv_cesa_hmac_ctx),
1336                         .cra_init = mv_cesa_ahmac_cra_init,
1337                         .cra_module = THIS_MODULE,
1338                 }
1339         }
1340 };
1341
1342 static int mv_cesa_ahmac_sha1_init(struct ahash_request *req)
1343 {
1344         struct mv_cesa_hmac_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
1345         struct mv_cesa_op_ctx tmpl = { };
1346
1347         mv_cesa_set_op_cfg(&tmpl, CESA_SA_DESC_CFG_MACM_HMAC_SHA1);
1348         memcpy(tmpl.ctx.hash.iv, ctx->iv, sizeof(ctx->iv));
1349
1350         mv_cesa_ahash_init(req, &tmpl, false);
1351
1352         return 0;
1353 }
1354
1355 static int mv_cesa_ahmac_sha1_setkey(struct crypto_ahash *tfm, const u8 *key,
1356                                      unsigned int keylen)
1357 {
1358         struct mv_cesa_hmac_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
1359         struct sha1_state istate, ostate;
1360         int ret, i;
1361
1362         ret = mv_cesa_ahmac_setkey("mv-sha1", key, keylen, &istate, &ostate);
1363         if (ret)
1364                 return ret;
1365
1366         for (i = 0; i < ARRAY_SIZE(istate.state); i++)
1367                 ctx->iv[i] = cpu_to_be32(istate.state[i]);
1368
1369         for (i = 0; i < ARRAY_SIZE(ostate.state); i++)
1370                 ctx->iv[i + 8] = cpu_to_be32(ostate.state[i]);
1371
1372         return 0;
1373 }
1374
1375 static int mv_cesa_ahmac_sha1_digest(struct ahash_request *req)
1376 {
1377         int ret;
1378
1379         ret = mv_cesa_ahmac_sha1_init(req);
1380         if (ret)
1381                 return ret;
1382
1383         return mv_cesa_ahash_finup(req);
1384 }
1385
1386 struct ahash_alg mv_ahmac_sha1_alg = {
1387         .init = mv_cesa_ahmac_sha1_init,
1388         .update = mv_cesa_ahash_update,
1389         .final = mv_cesa_ahash_final,
1390         .finup = mv_cesa_ahash_finup,
1391         .digest = mv_cesa_ahmac_sha1_digest,
1392         .setkey = mv_cesa_ahmac_sha1_setkey,
1393         .export = mv_cesa_sha1_export,
1394         .import = mv_cesa_sha1_import,
1395         .halg = {
1396                 .digestsize = SHA1_DIGEST_SIZE,
1397                 .statesize = sizeof(struct sha1_state),
1398                 .base = {
1399                         .cra_name = "hmac(sha1)",
1400                         .cra_driver_name = "mv-hmac-sha1",
1401                         .cra_priority = 300,
1402                         .cra_flags = CRYPTO_ALG_ASYNC |
1403                                      CRYPTO_ALG_ALLOCATES_MEMORY |
1404                                      CRYPTO_ALG_KERN_DRIVER_ONLY,
1405                         .cra_blocksize = SHA1_BLOCK_SIZE,
1406                         .cra_ctxsize = sizeof(struct mv_cesa_hmac_ctx),
1407                         .cra_init = mv_cesa_ahmac_cra_init,
1408                         .cra_module = THIS_MODULE,
1409                 }
1410         }
1411 };
1412
1413 static int mv_cesa_ahmac_sha256_setkey(struct crypto_ahash *tfm, const u8 *key,
1414                                        unsigned int keylen)
1415 {
1416         struct mv_cesa_hmac_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
1417         struct sha256_state istate, ostate;
1418         int ret, i;
1419
1420         ret = mv_cesa_ahmac_setkey("mv-sha256", key, keylen, &istate, &ostate);
1421         if (ret)
1422                 return ret;
1423
1424         for (i = 0; i < ARRAY_SIZE(istate.state); i++)
1425                 ctx->iv[i] = cpu_to_be32(istate.state[i]);
1426
1427         for (i = 0; i < ARRAY_SIZE(ostate.state); i++)
1428                 ctx->iv[i + 8] = cpu_to_be32(ostate.state[i]);
1429
1430         return 0;
1431 }
1432
1433 static int mv_cesa_ahmac_sha256_init(struct ahash_request *req)
1434 {
1435         struct mv_cesa_hmac_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
1436         struct mv_cesa_op_ctx tmpl = { };
1437
1438         mv_cesa_set_op_cfg(&tmpl, CESA_SA_DESC_CFG_MACM_HMAC_SHA256);
1439         memcpy(tmpl.ctx.hash.iv, ctx->iv, sizeof(ctx->iv));
1440
1441         mv_cesa_ahash_init(req, &tmpl, false);
1442
1443         return 0;
1444 }
1445
1446 static int mv_cesa_ahmac_sha256_digest(struct ahash_request *req)
1447 {
1448         int ret;
1449
1450         ret = mv_cesa_ahmac_sha256_init(req);
1451         if (ret)
1452                 return ret;
1453
1454         return mv_cesa_ahash_finup(req);
1455 }
1456
1457 struct ahash_alg mv_ahmac_sha256_alg = {
1458         .init = mv_cesa_ahmac_sha256_init,
1459         .update = mv_cesa_ahash_update,
1460         .final = mv_cesa_ahash_final,
1461         .finup = mv_cesa_ahash_finup,
1462         .digest = mv_cesa_ahmac_sha256_digest,
1463         .setkey = mv_cesa_ahmac_sha256_setkey,
1464         .export = mv_cesa_sha256_export,
1465         .import = mv_cesa_sha256_import,
1466         .halg = {
1467                 .digestsize = SHA256_DIGEST_SIZE,
1468                 .statesize = sizeof(struct sha256_state),
1469                 .base = {
1470                         .cra_name = "hmac(sha256)",
1471                         .cra_driver_name = "mv-hmac-sha256",
1472                         .cra_priority = 300,
1473                         .cra_flags = CRYPTO_ALG_ASYNC |
1474                                      CRYPTO_ALG_ALLOCATES_MEMORY |
1475                                      CRYPTO_ALG_KERN_DRIVER_ONLY,
1476                         .cra_blocksize = SHA256_BLOCK_SIZE,
1477                         .cra_ctxsize = sizeof(struct mv_cesa_hmac_ctx),
1478                         .cra_init = mv_cesa_ahmac_cra_init,
1479                         .cra_module = THIS_MODULE,
1480                 }
1481         }
1482 };