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 = 0, 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 = 0, 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 = 0, 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 static int mv_cesa_ahmac_iv_state_init(struct ahash_request *req, u8 *pad, 1108 void *state, unsigned int blocksize) 1109 { 1110 DECLARE_CRYPTO_WAIT(result); 1111 struct scatterlist sg; 1112 int ret; 1113 1114 ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 1115 crypto_req_done, &result); 1116 sg_init_one(&sg, pad, blocksize); 1117 ahash_request_set_crypt(req, &sg, pad, blocksize); 1118 1119 ret = crypto_ahash_init(req); 1120 if (ret) 1121 return ret; 1122 1123 ret = crypto_ahash_update(req); 1124 ret = crypto_wait_req(ret, &result); 1125 1126 if (ret) 1127 return ret; 1128 1129 ret = crypto_ahash_export(req, state); 1130 if (ret) 1131 return ret; 1132 1133 return 0; 1134 } 1135 1136 static int mv_cesa_ahmac_pad_init(struct ahash_request *req, 1137 const u8 *key, unsigned int keylen, 1138 u8 *ipad, u8 *opad, 1139 unsigned int blocksize) 1140 { 1141 DECLARE_CRYPTO_WAIT(result); 1142 struct scatterlist sg; 1143 int ret; 1144 int i; 1145 1146 if (keylen <= blocksize) { 1147 memcpy(ipad, key, keylen); 1148 } else { 1149 u8 *keydup = kmemdup(key, keylen, GFP_KERNEL); 1150 1151 if (!keydup) 1152 return -ENOMEM; 1153 1154 ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 1155 crypto_req_done, &result); 1156 sg_init_one(&sg, keydup, keylen); 1157 ahash_request_set_crypt(req, &sg, ipad, keylen); 1158 1159 ret = crypto_ahash_digest(req); 1160 ret = crypto_wait_req(ret, &result); 1161 1162 /* Set the memory region to 0 to avoid any leak. */ 1163 kfree_sensitive(keydup); 1164 1165 if (ret) 1166 return ret; 1167 1168 keylen = crypto_ahash_digestsize(crypto_ahash_reqtfm(req)); 1169 } 1170 1171 memset(ipad + keylen, 0, blocksize - keylen); 1172 memcpy(opad, ipad, blocksize); 1173 1174 for (i = 0; i < blocksize; i++) { 1175 ipad[i] ^= HMAC_IPAD_VALUE; 1176 opad[i] ^= HMAC_OPAD_VALUE; 1177 } 1178 1179 return 0; 1180 } 1181 1182 static int mv_cesa_ahmac_setkey(const char *hash_alg_name, 1183 const u8 *key, unsigned int keylen, 1184 void *istate, void *ostate) 1185 { 1186 struct ahash_request *req; 1187 struct crypto_ahash *tfm; 1188 unsigned int blocksize; 1189 u8 *ipad = NULL; 1190 u8 *opad; 1191 int ret; 1192 1193 tfm = crypto_alloc_ahash(hash_alg_name, 0, 0); 1194 if (IS_ERR(tfm)) 1195 return PTR_ERR(tfm); 1196 1197 req = ahash_request_alloc(tfm, GFP_KERNEL); 1198 if (!req) { 1199 ret = -ENOMEM; 1200 goto free_ahash; 1201 } 1202 1203 crypto_ahash_clear_flags(tfm, ~0); 1204 1205 blocksize = crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm)); 1206 1207 ipad = kcalloc(2, blocksize, GFP_KERNEL); 1208 if (!ipad) { 1209 ret = -ENOMEM; 1210 goto free_req; 1211 } 1212 1213 opad = ipad + blocksize; 1214 1215 ret = mv_cesa_ahmac_pad_init(req, key, keylen, ipad, opad, blocksize); 1216 if (ret) 1217 goto free_ipad; 1218 1219 ret = mv_cesa_ahmac_iv_state_init(req, ipad, istate, blocksize); 1220 if (ret) 1221 goto free_ipad; 1222 1223 ret = mv_cesa_ahmac_iv_state_init(req, opad, ostate, blocksize); 1224 1225 free_ipad: 1226 kfree(ipad); 1227 free_req: 1228 ahash_request_free(req); 1229 free_ahash: 1230 crypto_free_ahash(tfm); 1231 1232 return ret; 1233 } 1234 1235 static int mv_cesa_ahmac_cra_init(struct crypto_tfm *tfm) 1236 { 1237 struct mv_cesa_hmac_ctx *ctx = crypto_tfm_ctx(tfm); 1238 1239 ctx->base.ops = &mv_cesa_ahash_req_ops; 1240 1241 crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm), 1242 sizeof(struct mv_cesa_ahash_req)); 1243 return 0; 1244 } 1245 1246 static int mv_cesa_ahmac_md5_init(struct ahash_request *req) 1247 { 1248 struct mv_cesa_hmac_ctx *ctx = crypto_tfm_ctx(req->base.tfm); 1249 struct mv_cesa_op_ctx tmpl = { }; 1250 1251 mv_cesa_set_op_cfg(&tmpl, CESA_SA_DESC_CFG_MACM_HMAC_MD5); 1252 memcpy(tmpl.ctx.hash.iv, ctx->iv, sizeof(ctx->iv)); 1253 1254 mv_cesa_ahash_init(req, &tmpl, true); 1255 1256 return 0; 1257 } 1258 1259 static int mv_cesa_ahmac_md5_setkey(struct crypto_ahash *tfm, const u8 *key, 1260 unsigned int keylen) 1261 { 1262 struct mv_cesa_hmac_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm)); 1263 struct md5_state istate, ostate; 1264 int ret, i; 1265 1266 ret = mv_cesa_ahmac_setkey("mv-md5", key, keylen, &istate, &ostate); 1267 if (ret) 1268 return ret; 1269 1270 for (i = 0; i < ARRAY_SIZE(istate.hash); i++) 1271 ctx->iv[i] = cpu_to_be32(istate.hash[i]); 1272 1273 for (i = 0; i < ARRAY_SIZE(ostate.hash); i++) 1274 ctx->iv[i + 8] = cpu_to_be32(ostate.hash[i]); 1275 1276 return 0; 1277 } 1278 1279 static int mv_cesa_ahmac_md5_digest(struct ahash_request *req) 1280 { 1281 int ret; 1282 1283 ret = mv_cesa_ahmac_md5_init(req); 1284 if (ret) 1285 return ret; 1286 1287 return mv_cesa_ahash_finup(req); 1288 } 1289 1290 struct ahash_alg mv_ahmac_md5_alg = { 1291 .init = mv_cesa_ahmac_md5_init, 1292 .update = mv_cesa_ahash_update, 1293 .final = mv_cesa_ahash_final, 1294 .finup = mv_cesa_ahash_finup, 1295 .digest = mv_cesa_ahmac_md5_digest, 1296 .setkey = mv_cesa_ahmac_md5_setkey, 1297 .export = mv_cesa_md5_export, 1298 .import = mv_cesa_md5_import, 1299 .halg = { 1300 .digestsize = MD5_DIGEST_SIZE, 1301 .statesize = sizeof(struct md5_state), 1302 .base = { 1303 .cra_name = "hmac(md5)", 1304 .cra_driver_name = "mv-hmac-md5", 1305 .cra_priority = 0, 1306 .cra_flags = CRYPTO_ALG_ASYNC | 1307 CRYPTO_ALG_ALLOCATES_MEMORY | 1308 CRYPTO_ALG_KERN_DRIVER_ONLY, 1309 .cra_blocksize = MD5_HMAC_BLOCK_SIZE, 1310 .cra_ctxsize = sizeof(struct mv_cesa_hmac_ctx), 1311 .cra_init = mv_cesa_ahmac_cra_init, 1312 .cra_module = THIS_MODULE, 1313 } 1314 } 1315 }; 1316 1317 static int mv_cesa_ahmac_sha1_init(struct ahash_request *req) 1318 { 1319 struct mv_cesa_hmac_ctx *ctx = crypto_tfm_ctx(req->base.tfm); 1320 struct mv_cesa_op_ctx tmpl = { }; 1321 1322 mv_cesa_set_op_cfg(&tmpl, CESA_SA_DESC_CFG_MACM_HMAC_SHA1); 1323 memcpy(tmpl.ctx.hash.iv, ctx->iv, sizeof(ctx->iv)); 1324 1325 mv_cesa_ahash_init(req, &tmpl, false); 1326 1327 return 0; 1328 } 1329 1330 static int mv_cesa_ahmac_sha1_setkey(struct crypto_ahash *tfm, const u8 *key, 1331 unsigned int keylen) 1332 { 1333 struct mv_cesa_hmac_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm)); 1334 struct sha1_state istate, ostate; 1335 int ret, i; 1336 1337 ret = mv_cesa_ahmac_setkey("mv-sha1", key, keylen, &istate, &ostate); 1338 if (ret) 1339 return ret; 1340 1341 for (i = 0; i < ARRAY_SIZE(istate.state); i++) 1342 ctx->iv[i] = cpu_to_be32(istate.state[i]); 1343 1344 for (i = 0; i < ARRAY_SIZE(ostate.state); i++) 1345 ctx->iv[i + 8] = cpu_to_be32(ostate.state[i]); 1346 1347 return 0; 1348 } 1349 1350 static int mv_cesa_ahmac_sha1_digest(struct ahash_request *req) 1351 { 1352 int ret; 1353 1354 ret = mv_cesa_ahmac_sha1_init(req); 1355 if (ret) 1356 return ret; 1357 1358 return mv_cesa_ahash_finup(req); 1359 } 1360 1361 struct ahash_alg mv_ahmac_sha1_alg = { 1362 .init = mv_cesa_ahmac_sha1_init, 1363 .update = mv_cesa_ahash_update, 1364 .final = mv_cesa_ahash_final, 1365 .finup = mv_cesa_ahash_finup, 1366 .digest = mv_cesa_ahmac_sha1_digest, 1367 .setkey = mv_cesa_ahmac_sha1_setkey, 1368 .export = mv_cesa_sha1_export, 1369 .import = mv_cesa_sha1_import, 1370 .halg = { 1371 .digestsize = SHA1_DIGEST_SIZE, 1372 .statesize = sizeof(struct sha1_state), 1373 .base = { 1374 .cra_name = "hmac(sha1)", 1375 .cra_driver_name = "mv-hmac-sha1", 1376 .cra_priority = 0, 1377 .cra_flags = CRYPTO_ALG_ASYNC | 1378 CRYPTO_ALG_ALLOCATES_MEMORY | 1379 CRYPTO_ALG_KERN_DRIVER_ONLY, 1380 .cra_blocksize = SHA1_BLOCK_SIZE, 1381 .cra_ctxsize = sizeof(struct mv_cesa_hmac_ctx), 1382 .cra_init = mv_cesa_ahmac_cra_init, 1383 .cra_module = THIS_MODULE, 1384 } 1385 } 1386 }; 1387 1388 static int mv_cesa_ahmac_sha256_setkey(struct crypto_ahash *tfm, const u8 *key, 1389 unsigned int keylen) 1390 { 1391 struct mv_cesa_hmac_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm)); 1392 struct sha256_state istate, ostate; 1393 int ret, i; 1394 1395 ret = mv_cesa_ahmac_setkey("mv-sha256", key, keylen, &istate, &ostate); 1396 if (ret) 1397 return ret; 1398 1399 for (i = 0; i < ARRAY_SIZE(istate.state); i++) 1400 ctx->iv[i] = cpu_to_be32(istate.state[i]); 1401 1402 for (i = 0; i < ARRAY_SIZE(ostate.state); i++) 1403 ctx->iv[i + 8] = cpu_to_be32(ostate.state[i]); 1404 1405 return 0; 1406 } 1407 1408 static int mv_cesa_ahmac_sha256_init(struct ahash_request *req) 1409 { 1410 struct mv_cesa_hmac_ctx *ctx = crypto_tfm_ctx(req->base.tfm); 1411 struct mv_cesa_op_ctx tmpl = { }; 1412 1413 mv_cesa_set_op_cfg(&tmpl, CESA_SA_DESC_CFG_MACM_HMAC_SHA256); 1414 memcpy(tmpl.ctx.hash.iv, ctx->iv, sizeof(ctx->iv)); 1415 1416 mv_cesa_ahash_init(req, &tmpl, false); 1417 1418 return 0; 1419 } 1420 1421 static int mv_cesa_ahmac_sha256_digest(struct ahash_request *req) 1422 { 1423 int ret; 1424 1425 ret = mv_cesa_ahmac_sha256_init(req); 1426 if (ret) 1427 return ret; 1428 1429 return mv_cesa_ahash_finup(req); 1430 } 1431 1432 struct ahash_alg mv_ahmac_sha256_alg = { 1433 .init = mv_cesa_ahmac_sha256_init, 1434 .update = mv_cesa_ahash_update, 1435 .final = mv_cesa_ahash_final, 1436 .finup = mv_cesa_ahash_finup, 1437 .digest = mv_cesa_ahmac_sha256_digest, 1438 .setkey = mv_cesa_ahmac_sha256_setkey, 1439 .export = mv_cesa_sha256_export, 1440 .import = mv_cesa_sha256_import, 1441 .halg = { 1442 .digestsize = SHA256_DIGEST_SIZE, 1443 .statesize = sizeof(struct sha256_state), 1444 .base = { 1445 .cra_name = "hmac(sha256)", 1446 .cra_driver_name = "mv-hmac-sha256", 1447 .cra_priority = 0, 1448 .cra_flags = CRYPTO_ALG_ASYNC | 1449 CRYPTO_ALG_ALLOCATES_MEMORY | 1450 CRYPTO_ALG_KERN_DRIVER_ONLY, 1451 .cra_blocksize = SHA256_BLOCK_SIZE, 1452 .cra_ctxsize = sizeof(struct mv_cesa_hmac_ctx), 1453 .cra_init = mv_cesa_ahmac_cra_init, 1454 .cra_module = THIS_MODULE, 1455 } 1456 } 1457 }; 1458