1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Hash function and HMAC support for StarFive driver 4 * 5 * Copyright (c) 2022 StarFive Technology 6 * 7 */ 8 9 #include <crypto/engine.h> 10 #include <crypto/internal/hash.h> 11 #include <crypto/scatterwalk.h> 12 #include "jh7110-cryp.h" 13 #include <linux/amba/pl080.h> 14 #include <linux/clk.h> 15 #include <linux/dma-direct.h> 16 #include <linux/interrupt.h> 17 #include <linux/iopoll.h> 18 #include <linux/kernel.h> 19 #include <linux/module.h> 20 #include <linux/platform_device.h> 21 #include <linux/pm_runtime.h> 22 #include <linux/reset.h> 23 24 #define STARFIVE_HASH_REGS_OFFSET 0x300 25 #define STARFIVE_HASH_SHACSR (STARFIVE_HASH_REGS_OFFSET + 0x0) 26 #define STARFIVE_HASH_SHAWDR (STARFIVE_HASH_REGS_OFFSET + 0x4) 27 #define STARFIVE_HASH_SHARDR (STARFIVE_HASH_REGS_OFFSET + 0x8) 28 #define STARFIVE_HASH_SHAWSR (STARFIVE_HASH_REGS_OFFSET + 0xC) 29 #define STARFIVE_HASH_SHAWLEN3 (STARFIVE_HASH_REGS_OFFSET + 0x10) 30 #define STARFIVE_HASH_SHAWLEN2 (STARFIVE_HASH_REGS_OFFSET + 0x14) 31 #define STARFIVE_HASH_SHAWLEN1 (STARFIVE_HASH_REGS_OFFSET + 0x18) 32 #define STARFIVE_HASH_SHAWLEN0 (STARFIVE_HASH_REGS_OFFSET + 0x1C) 33 #define STARFIVE_HASH_SHAWKR (STARFIVE_HASH_REGS_OFFSET + 0x20) 34 #define STARFIVE_HASH_SHAWKLEN (STARFIVE_HASH_REGS_OFFSET + 0x24) 35 36 #define STARFIVE_HASH_BUFLEN SHA512_BLOCK_SIZE 37 #define STARFIVE_HASH_RESET 0x2 38 39 static inline int starfive_hash_wait_busy(struct starfive_cryp_ctx *ctx) 40 { 41 struct starfive_cryp_dev *cryp = ctx->cryp; 42 u32 status; 43 44 return readl_relaxed_poll_timeout(cryp->base + STARFIVE_HASH_SHACSR, status, 45 !(status & STARFIVE_HASH_BUSY), 10, 100000); 46 } 47 48 static inline int starfive_hash_wait_key_done(struct starfive_cryp_ctx *ctx) 49 { 50 struct starfive_cryp_dev *cryp = ctx->cryp; 51 u32 status; 52 53 return readl_relaxed_poll_timeout(cryp->base + STARFIVE_HASH_SHACSR, status, 54 (status & STARFIVE_HASH_KEY_DONE), 10, 100000); 55 } 56 57 static int starfive_hash_hmac_key(struct starfive_cryp_ctx *ctx) 58 { 59 struct starfive_cryp_request_ctx *rctx = ctx->rctx; 60 struct starfive_cryp_dev *cryp = ctx->cryp; 61 int klen = ctx->keylen, loop; 62 unsigned int *key = (unsigned int *)ctx->key; 63 unsigned char *cl; 64 65 writel(ctx->keylen, cryp->base + STARFIVE_HASH_SHAWKLEN); 66 67 rctx->csr.hash.hmac = 1; 68 rctx->csr.hash.key_flag = 1; 69 70 writel(rctx->csr.hash.v, cryp->base + STARFIVE_HASH_SHACSR); 71 72 for (loop = 0; loop < klen / sizeof(unsigned int); loop++, key++) 73 writel(*key, cryp->base + STARFIVE_HASH_SHAWKR); 74 75 if (klen & 0x3) { 76 cl = (unsigned char *)key; 77 for (loop = 0; loop < (klen & 0x3); loop++, cl++) 78 writeb(*cl, cryp->base + STARFIVE_HASH_SHAWKR); 79 } 80 81 if (starfive_hash_wait_key_done(ctx)) 82 return dev_err_probe(cryp->dev, -ETIMEDOUT, "starfive_hash_wait_key_done error\n"); 83 84 return 0; 85 } 86 87 static void starfive_hash_start(void *param) 88 { 89 struct starfive_cryp_ctx *ctx = param; 90 struct starfive_cryp_request_ctx *rctx = ctx->rctx; 91 struct starfive_cryp_dev *cryp = ctx->cryp; 92 union starfive_alg_cr alg_cr; 93 union starfive_hash_csr csr; 94 u32 stat; 95 96 dma_unmap_sg(cryp->dev, rctx->in_sg, rctx->in_sg_len, DMA_TO_DEVICE); 97 98 alg_cr.v = 0; 99 alg_cr.clear = 1; 100 101 writel(alg_cr.v, cryp->base + STARFIVE_ALG_CR_OFFSET); 102 103 csr.v = readl(cryp->base + STARFIVE_HASH_SHACSR); 104 csr.firstb = 0; 105 csr.final = 1; 106 107 stat = readl(cryp->base + STARFIVE_IE_MASK_OFFSET); 108 stat &= ~STARFIVE_IE_MASK_HASH_DONE; 109 writel(stat, cryp->base + STARFIVE_IE_MASK_OFFSET); 110 writel(csr.v, cryp->base + STARFIVE_HASH_SHACSR); 111 } 112 113 static int starfive_hash_xmit_dma(struct starfive_cryp_ctx *ctx) 114 { 115 struct starfive_cryp_request_ctx *rctx = ctx->rctx; 116 struct starfive_cryp_dev *cryp = ctx->cryp; 117 struct dma_async_tx_descriptor *in_desc; 118 union starfive_alg_cr alg_cr; 119 int total_len; 120 int ret; 121 122 if (!rctx->total) { 123 starfive_hash_start(ctx); 124 return 0; 125 } 126 127 writel(rctx->total, cryp->base + STARFIVE_DMA_IN_LEN_OFFSET); 128 129 total_len = rctx->total; 130 total_len = (total_len & 0x3) ? (((total_len >> 2) + 1) << 2) : total_len; 131 sg_dma_len(rctx->in_sg) = total_len; 132 133 alg_cr.v = 0; 134 alg_cr.start = 1; 135 alg_cr.hash_dma_en = 1; 136 137 writel(alg_cr.v, cryp->base + STARFIVE_ALG_CR_OFFSET); 138 139 ret = dma_map_sg(cryp->dev, rctx->in_sg, rctx->in_sg_len, DMA_TO_DEVICE); 140 if (!ret) 141 return dev_err_probe(cryp->dev, -EINVAL, "dma_map_sg() error\n"); 142 143 cryp->cfg_in.direction = DMA_MEM_TO_DEV; 144 cryp->cfg_in.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; 145 cryp->cfg_in.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; 146 cryp->cfg_in.src_maxburst = cryp->dma_maxburst; 147 cryp->cfg_in.dst_maxburst = cryp->dma_maxburst; 148 cryp->cfg_in.dst_addr = cryp->phys_base + STARFIVE_ALG_FIFO_OFFSET; 149 150 dmaengine_slave_config(cryp->tx, &cryp->cfg_in); 151 152 in_desc = dmaengine_prep_slave_sg(cryp->tx, rctx->in_sg, 153 ret, DMA_MEM_TO_DEV, 154 DMA_PREP_INTERRUPT | DMA_CTRL_ACK); 155 156 if (!in_desc) 157 return -EINVAL; 158 159 in_desc->callback = starfive_hash_start; 160 in_desc->callback_param = ctx; 161 162 dmaengine_submit(in_desc); 163 dma_async_issue_pending(cryp->tx); 164 165 return 0; 166 } 167 168 static int starfive_hash_xmit(struct starfive_cryp_ctx *ctx) 169 { 170 struct starfive_cryp_request_ctx *rctx = ctx->rctx; 171 struct starfive_cryp_dev *cryp = ctx->cryp; 172 int ret = 0; 173 174 rctx->csr.hash.v = 0; 175 rctx->csr.hash.reset = 1; 176 writel(rctx->csr.hash.v, cryp->base + STARFIVE_HASH_SHACSR); 177 178 if (starfive_hash_wait_busy(ctx)) 179 return dev_err_probe(cryp->dev, -ETIMEDOUT, "Error resetting engine.\n"); 180 181 rctx->csr.hash.v = 0; 182 rctx->csr.hash.mode = ctx->hash_mode; 183 rctx->csr.hash.ie = 1; 184 185 if (ctx->is_hmac) { 186 ret = starfive_hash_hmac_key(ctx); 187 if (ret) 188 return ret; 189 } else { 190 rctx->csr.hash.start = 1; 191 rctx->csr.hash.firstb = 1; 192 writel(rctx->csr.hash.v, cryp->base + STARFIVE_HASH_SHACSR); 193 } 194 195 return starfive_hash_xmit_dma(ctx); 196 } 197 198 static int starfive_hash_copy_hash(struct ahash_request *req) 199 { 200 struct starfive_cryp_request_ctx *rctx = ahash_request_ctx(req); 201 struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req)); 202 int count, *data; 203 int mlen; 204 205 if (!req->result) 206 return 0; 207 208 mlen = rctx->digsize / sizeof(u32); 209 data = (u32 *)req->result; 210 211 for (count = 0; count < mlen; count++) 212 put_unaligned(readl(ctx->cryp->base + STARFIVE_HASH_SHARDR), 213 &data[count]); 214 215 return 0; 216 } 217 218 void starfive_hash_done_task(unsigned long param) 219 { 220 struct starfive_cryp_dev *cryp = (struct starfive_cryp_dev *)param; 221 int err = cryp->err; 222 223 if (!err) 224 err = starfive_hash_copy_hash(cryp->req.hreq); 225 226 /* Reset to clear hash_done in irq register*/ 227 writel(STARFIVE_HASH_RESET, cryp->base + STARFIVE_HASH_SHACSR); 228 229 crypto_finalize_hash_request(cryp->engine, cryp->req.hreq, err); 230 } 231 232 static int starfive_hash_check_aligned(struct scatterlist *sg, size_t total, size_t align) 233 { 234 int len = 0; 235 236 if (!total) 237 return 0; 238 239 if (!IS_ALIGNED(total, align)) 240 return -EINVAL; 241 242 while (sg) { 243 if (!IS_ALIGNED(sg->offset, sizeof(u32))) 244 return -EINVAL; 245 246 if (!IS_ALIGNED(sg->length, align)) 247 return -EINVAL; 248 249 len += sg->length; 250 sg = sg_next(sg); 251 } 252 253 if (len != total) 254 return -EINVAL; 255 256 return 0; 257 } 258 259 static int starfive_hash_one_request(struct crypto_engine *engine, void *areq) 260 { 261 struct ahash_request *req = container_of(areq, struct ahash_request, 262 base); 263 struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req)); 264 struct starfive_cryp_dev *cryp = ctx->cryp; 265 266 if (!cryp) 267 return -ENODEV; 268 269 return starfive_hash_xmit(ctx); 270 } 271 272 static int starfive_hash_init(struct ahash_request *req) 273 { 274 struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); 275 struct starfive_cryp_request_ctx *rctx = ahash_request_ctx(req); 276 struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(tfm); 277 278 ahash_request_set_tfm(&rctx->ahash_fbk_req, ctx->ahash_fbk); 279 ahash_request_set_callback(&rctx->ahash_fbk_req, 280 req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP, 281 req->base.complete, req->base.data); 282 283 ahash_request_set_crypt(&rctx->ahash_fbk_req, req->src, 284 req->result, req->nbytes); 285 286 return crypto_ahash_init(&rctx->ahash_fbk_req); 287 } 288 289 static int starfive_hash_update(struct ahash_request *req) 290 { 291 struct starfive_cryp_request_ctx *rctx = ahash_request_ctx(req); 292 struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); 293 struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(tfm); 294 295 ahash_request_set_tfm(&rctx->ahash_fbk_req, ctx->ahash_fbk); 296 ahash_request_set_callback(&rctx->ahash_fbk_req, 297 req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP, 298 req->base.complete, req->base.data); 299 300 ahash_request_set_crypt(&rctx->ahash_fbk_req, req->src, 301 req->result, req->nbytes); 302 303 return crypto_ahash_update(&rctx->ahash_fbk_req); 304 } 305 306 static int starfive_hash_final(struct ahash_request *req) 307 { 308 struct starfive_cryp_request_ctx *rctx = ahash_request_ctx(req); 309 struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); 310 struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(tfm); 311 312 ahash_request_set_tfm(&rctx->ahash_fbk_req, ctx->ahash_fbk); 313 ahash_request_set_callback(&rctx->ahash_fbk_req, 314 req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP, 315 req->base.complete, req->base.data); 316 317 ahash_request_set_crypt(&rctx->ahash_fbk_req, req->src, 318 req->result, req->nbytes); 319 320 return crypto_ahash_final(&rctx->ahash_fbk_req); 321 } 322 323 static int starfive_hash_finup(struct ahash_request *req) 324 { 325 struct starfive_cryp_request_ctx *rctx = ahash_request_ctx(req); 326 struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); 327 struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(tfm); 328 329 ahash_request_set_tfm(&rctx->ahash_fbk_req, ctx->ahash_fbk); 330 ahash_request_set_callback(&rctx->ahash_fbk_req, 331 req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP, 332 req->base.complete, req->base.data); 333 334 ahash_request_set_crypt(&rctx->ahash_fbk_req, req->src, 335 req->result, req->nbytes); 336 337 return crypto_ahash_finup(&rctx->ahash_fbk_req); 338 } 339 340 static int starfive_hash_digest_fb(struct ahash_request *req) 341 { 342 struct starfive_cryp_request_ctx *rctx = ahash_request_ctx(req); 343 struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); 344 struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(tfm); 345 346 ahash_request_set_tfm(&rctx->ahash_fbk_req, ctx->ahash_fbk); 347 ahash_request_set_callback(&rctx->ahash_fbk_req, req->base.flags, 348 req->base.complete, req->base.data); 349 350 ahash_request_set_crypt(&rctx->ahash_fbk_req, req->src, 351 req->result, req->nbytes); 352 353 return crypto_ahash_digest(&rctx->ahash_fbk_req); 354 } 355 356 static int starfive_hash_digest(struct ahash_request *req) 357 { 358 struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); 359 struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(tfm); 360 struct starfive_cryp_request_ctx *rctx = ahash_request_ctx(req); 361 struct starfive_cryp_dev *cryp = ctx->cryp; 362 363 memset(rctx, 0, sizeof(struct starfive_cryp_request_ctx)); 364 365 cryp->req.hreq = req; 366 rctx->total = req->nbytes; 367 rctx->in_sg = req->src; 368 rctx->blksize = crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm)); 369 rctx->digsize = crypto_ahash_digestsize(tfm); 370 rctx->in_sg_len = sg_nents_for_len(rctx->in_sg, rctx->total); 371 ctx->rctx = rctx; 372 373 if (starfive_hash_check_aligned(rctx->in_sg, rctx->total, rctx->blksize)) 374 return starfive_hash_digest_fb(req); 375 376 return crypto_transfer_hash_request_to_engine(cryp->engine, req); 377 } 378 379 static int starfive_hash_export(struct ahash_request *req, void *out) 380 { 381 struct starfive_cryp_request_ctx *rctx = ahash_request_ctx(req); 382 struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); 383 struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(tfm); 384 385 ahash_request_set_tfm(&rctx->ahash_fbk_req, ctx->ahash_fbk); 386 ahash_request_set_callback(&rctx->ahash_fbk_req, 387 req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP, 388 req->base.complete, req->base.data); 389 390 return crypto_ahash_export(&rctx->ahash_fbk_req, out); 391 } 392 393 static int starfive_hash_import(struct ahash_request *req, const void *in) 394 { 395 struct starfive_cryp_request_ctx *rctx = ahash_request_ctx(req); 396 struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); 397 struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(tfm); 398 399 ahash_request_set_tfm(&rctx->ahash_fbk_req, ctx->ahash_fbk); 400 ahash_request_set_callback(&rctx->ahash_fbk_req, 401 req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP, 402 req->base.complete, req->base.data); 403 404 return crypto_ahash_import(&rctx->ahash_fbk_req, in); 405 } 406 407 static int starfive_hash_init_tfm(struct crypto_ahash *hash, 408 const char *alg_name, 409 unsigned int mode) 410 { 411 struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(hash); 412 413 ctx->cryp = starfive_cryp_find_dev(ctx); 414 415 if (!ctx->cryp) 416 return -ENODEV; 417 418 ctx->ahash_fbk = crypto_alloc_ahash(alg_name, 0, 419 CRYPTO_ALG_NEED_FALLBACK); 420 421 if (IS_ERR(ctx->ahash_fbk)) 422 return dev_err_probe(ctx->cryp->dev, PTR_ERR(ctx->ahash_fbk), 423 "starfive_hash: Could not load fallback driver.\n"); 424 425 crypto_ahash_set_statesize(hash, crypto_ahash_statesize(ctx->ahash_fbk)); 426 crypto_ahash_set_reqsize(hash, sizeof(struct starfive_cryp_request_ctx) + 427 crypto_ahash_reqsize(ctx->ahash_fbk)); 428 429 ctx->keylen = 0; 430 ctx->hash_mode = mode; 431 432 return 0; 433 } 434 435 static void starfive_hash_exit_tfm(struct crypto_ahash *hash) 436 { 437 struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(hash); 438 439 crypto_free_ahash(ctx->ahash_fbk); 440 } 441 442 static int starfive_hash_long_setkey(struct starfive_cryp_ctx *ctx, 443 const u8 *key, unsigned int keylen, 444 const char *alg_name) 445 { 446 struct crypto_wait wait; 447 struct ahash_request *req; 448 struct scatterlist sg; 449 struct crypto_ahash *ahash_tfm; 450 u8 *buf; 451 int ret; 452 453 ahash_tfm = crypto_alloc_ahash(alg_name, 0, 0); 454 if (IS_ERR(ahash_tfm)) 455 return PTR_ERR(ahash_tfm); 456 457 req = ahash_request_alloc(ahash_tfm, GFP_KERNEL); 458 if (!req) { 459 ret = -ENOMEM; 460 goto err_free_ahash; 461 } 462 463 crypto_init_wait(&wait); 464 ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 465 crypto_req_done, &wait); 466 crypto_ahash_clear_flags(ahash_tfm, ~0); 467 468 buf = kzalloc(keylen + STARFIVE_HASH_BUFLEN, GFP_KERNEL); 469 if (!buf) { 470 ret = -ENOMEM; 471 goto err_free_req; 472 } 473 474 memcpy(buf, key, keylen); 475 sg_init_one(&sg, buf, keylen); 476 ahash_request_set_crypt(req, &sg, ctx->key, keylen); 477 478 ret = crypto_wait_req(crypto_ahash_digest(req), &wait); 479 480 kfree(buf); 481 err_free_req: 482 ahash_request_free(req); 483 err_free_ahash: 484 crypto_free_ahash(ahash_tfm); 485 return ret; 486 } 487 488 static int starfive_hash_setkey(struct crypto_ahash *hash, 489 const u8 *key, unsigned int keylen) 490 { 491 struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(hash); 492 unsigned int digestsize = crypto_ahash_digestsize(hash); 493 unsigned int blocksize = crypto_ahash_blocksize(hash); 494 const char *alg_name; 495 496 crypto_ahash_setkey(ctx->ahash_fbk, key, keylen); 497 498 if (keylen <= blocksize) { 499 memcpy(ctx->key, key, keylen); 500 ctx->keylen = keylen; 501 return 0; 502 } 503 504 ctx->keylen = digestsize; 505 506 switch (digestsize) { 507 case SHA224_DIGEST_SIZE: 508 alg_name = "sha224-starfive"; 509 break; 510 case SHA256_DIGEST_SIZE: 511 if (ctx->hash_mode == STARFIVE_HASH_SM3) 512 alg_name = "sm3-starfive"; 513 else 514 alg_name = "sha256-starfive"; 515 break; 516 case SHA384_DIGEST_SIZE: 517 alg_name = "sha384-starfive"; 518 break; 519 case SHA512_DIGEST_SIZE: 520 alg_name = "sha512-starfive"; 521 break; 522 default: 523 return -EINVAL; 524 } 525 526 return starfive_hash_long_setkey(ctx, key, keylen, alg_name); 527 } 528 529 static int starfive_sha224_init_tfm(struct crypto_ahash *hash) 530 { 531 return starfive_hash_init_tfm(hash, "sha224-generic", 532 STARFIVE_HASH_SHA224); 533 } 534 535 static int starfive_sha256_init_tfm(struct crypto_ahash *hash) 536 { 537 return starfive_hash_init_tfm(hash, "sha256-generic", 538 STARFIVE_HASH_SHA256); 539 } 540 541 static int starfive_sha384_init_tfm(struct crypto_ahash *hash) 542 { 543 return starfive_hash_init_tfm(hash, "sha384-generic", 544 STARFIVE_HASH_SHA384); 545 } 546 547 static int starfive_sha512_init_tfm(struct crypto_ahash *hash) 548 { 549 return starfive_hash_init_tfm(hash, "sha512-generic", 550 STARFIVE_HASH_SHA512); 551 } 552 553 static int starfive_sm3_init_tfm(struct crypto_ahash *hash) 554 { 555 return starfive_hash_init_tfm(hash, "sm3-generic", 556 STARFIVE_HASH_SM3); 557 } 558 559 static int starfive_hmac_sha224_init_tfm(struct crypto_ahash *hash) 560 { 561 struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(hash); 562 563 ctx->is_hmac = true; 564 565 return starfive_hash_init_tfm(hash, "hmac(sha224-generic)", 566 STARFIVE_HASH_SHA224); 567 } 568 569 static int starfive_hmac_sha256_init_tfm(struct crypto_ahash *hash) 570 { 571 struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(hash); 572 573 ctx->is_hmac = true; 574 575 return starfive_hash_init_tfm(hash, "hmac(sha256-generic)", 576 STARFIVE_HASH_SHA256); 577 } 578 579 static int starfive_hmac_sha384_init_tfm(struct crypto_ahash *hash) 580 { 581 struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(hash); 582 583 ctx->is_hmac = true; 584 585 return starfive_hash_init_tfm(hash, "hmac(sha384-generic)", 586 STARFIVE_HASH_SHA384); 587 } 588 589 static int starfive_hmac_sha512_init_tfm(struct crypto_ahash *hash) 590 { 591 struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(hash); 592 593 ctx->is_hmac = true; 594 595 return starfive_hash_init_tfm(hash, "hmac(sha512-generic)", 596 STARFIVE_HASH_SHA512); 597 } 598 599 static int starfive_hmac_sm3_init_tfm(struct crypto_ahash *hash) 600 { 601 struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(hash); 602 603 ctx->is_hmac = true; 604 605 return starfive_hash_init_tfm(hash, "hmac(sm3-generic)", 606 STARFIVE_HASH_SM3); 607 } 608 609 static struct ahash_engine_alg algs_sha2_sm3[] = { 610 { 611 .base.init = starfive_hash_init, 612 .base.update = starfive_hash_update, 613 .base.final = starfive_hash_final, 614 .base.finup = starfive_hash_finup, 615 .base.digest = starfive_hash_digest, 616 .base.export = starfive_hash_export, 617 .base.import = starfive_hash_import, 618 .base.init_tfm = starfive_sha224_init_tfm, 619 .base.exit_tfm = starfive_hash_exit_tfm, 620 .base.halg = { 621 .digestsize = SHA224_DIGEST_SIZE, 622 .statesize = sizeof(struct sha256_state), 623 .base = { 624 .cra_name = "sha224", 625 .cra_driver_name = "sha224-starfive", 626 .cra_priority = 200, 627 .cra_flags = CRYPTO_ALG_ASYNC | 628 CRYPTO_ALG_TYPE_AHASH | 629 CRYPTO_ALG_NEED_FALLBACK, 630 .cra_blocksize = SHA224_BLOCK_SIZE, 631 .cra_ctxsize = sizeof(struct starfive_cryp_ctx), 632 .cra_module = THIS_MODULE, 633 } 634 }, 635 .op = { 636 .do_one_request = starfive_hash_one_request, 637 }, 638 }, { 639 .base.init = starfive_hash_init, 640 .base.update = starfive_hash_update, 641 .base.final = starfive_hash_final, 642 .base.finup = starfive_hash_finup, 643 .base.digest = starfive_hash_digest, 644 .base.export = starfive_hash_export, 645 .base.import = starfive_hash_import, 646 .base.init_tfm = starfive_hmac_sha224_init_tfm, 647 .base.exit_tfm = starfive_hash_exit_tfm, 648 .base.setkey = starfive_hash_setkey, 649 .base.halg = { 650 .digestsize = SHA224_DIGEST_SIZE, 651 .statesize = sizeof(struct sha256_state), 652 .base = { 653 .cra_name = "hmac(sha224)", 654 .cra_driver_name = "sha224-hmac-starfive", 655 .cra_priority = 200, 656 .cra_flags = CRYPTO_ALG_ASYNC | 657 CRYPTO_ALG_TYPE_AHASH | 658 CRYPTO_ALG_NEED_FALLBACK, 659 .cra_blocksize = SHA224_BLOCK_SIZE, 660 .cra_ctxsize = sizeof(struct starfive_cryp_ctx), 661 .cra_module = THIS_MODULE, 662 } 663 }, 664 .op = { 665 .do_one_request = starfive_hash_one_request, 666 }, 667 }, { 668 .base.init = starfive_hash_init, 669 .base.update = starfive_hash_update, 670 .base.final = starfive_hash_final, 671 .base.finup = starfive_hash_finup, 672 .base.digest = starfive_hash_digest, 673 .base.export = starfive_hash_export, 674 .base.import = starfive_hash_import, 675 .base.init_tfm = starfive_sha256_init_tfm, 676 .base.exit_tfm = starfive_hash_exit_tfm, 677 .base.halg = { 678 .digestsize = SHA256_DIGEST_SIZE, 679 .statesize = sizeof(struct sha256_state), 680 .base = { 681 .cra_name = "sha256", 682 .cra_driver_name = "sha256-starfive", 683 .cra_priority = 200, 684 .cra_flags = CRYPTO_ALG_ASYNC | 685 CRYPTO_ALG_TYPE_AHASH | 686 CRYPTO_ALG_NEED_FALLBACK, 687 .cra_blocksize = SHA256_BLOCK_SIZE, 688 .cra_ctxsize = sizeof(struct starfive_cryp_ctx), 689 .cra_module = THIS_MODULE, 690 } 691 }, 692 .op = { 693 .do_one_request = starfive_hash_one_request, 694 }, 695 }, { 696 .base.init = starfive_hash_init, 697 .base.update = starfive_hash_update, 698 .base.final = starfive_hash_final, 699 .base.finup = starfive_hash_finup, 700 .base.digest = starfive_hash_digest, 701 .base.export = starfive_hash_export, 702 .base.import = starfive_hash_import, 703 .base.init_tfm = starfive_hmac_sha256_init_tfm, 704 .base.exit_tfm = starfive_hash_exit_tfm, 705 .base.setkey = starfive_hash_setkey, 706 .base.halg = { 707 .digestsize = SHA256_DIGEST_SIZE, 708 .statesize = sizeof(struct sha256_state), 709 .base = { 710 .cra_name = "hmac(sha256)", 711 .cra_driver_name = "sha256-hmac-starfive", 712 .cra_priority = 200, 713 .cra_flags = CRYPTO_ALG_ASYNC | 714 CRYPTO_ALG_TYPE_AHASH | 715 CRYPTO_ALG_NEED_FALLBACK, 716 .cra_blocksize = SHA256_BLOCK_SIZE, 717 .cra_ctxsize = sizeof(struct starfive_cryp_ctx), 718 .cra_module = THIS_MODULE, 719 } 720 }, 721 .op = { 722 .do_one_request = starfive_hash_one_request, 723 }, 724 }, { 725 .base.init = starfive_hash_init, 726 .base.update = starfive_hash_update, 727 .base.final = starfive_hash_final, 728 .base.finup = starfive_hash_finup, 729 .base.digest = starfive_hash_digest, 730 .base.export = starfive_hash_export, 731 .base.import = starfive_hash_import, 732 .base.init_tfm = starfive_sha384_init_tfm, 733 .base.exit_tfm = starfive_hash_exit_tfm, 734 .base.halg = { 735 .digestsize = SHA384_DIGEST_SIZE, 736 .statesize = sizeof(struct sha512_state), 737 .base = { 738 .cra_name = "sha384", 739 .cra_driver_name = "sha384-starfive", 740 .cra_priority = 200, 741 .cra_flags = CRYPTO_ALG_ASYNC | 742 CRYPTO_ALG_TYPE_AHASH | 743 CRYPTO_ALG_NEED_FALLBACK, 744 .cra_blocksize = SHA384_BLOCK_SIZE, 745 .cra_ctxsize = sizeof(struct starfive_cryp_ctx), 746 .cra_module = THIS_MODULE, 747 } 748 }, 749 .op = { 750 .do_one_request = starfive_hash_one_request, 751 }, 752 }, { 753 .base.init = starfive_hash_init, 754 .base.update = starfive_hash_update, 755 .base.final = starfive_hash_final, 756 .base.finup = starfive_hash_finup, 757 .base.digest = starfive_hash_digest, 758 .base.export = starfive_hash_export, 759 .base.import = starfive_hash_import, 760 .base.init_tfm = starfive_hmac_sha384_init_tfm, 761 .base.exit_tfm = starfive_hash_exit_tfm, 762 .base.setkey = starfive_hash_setkey, 763 .base.halg = { 764 .digestsize = SHA384_DIGEST_SIZE, 765 .statesize = sizeof(struct sha512_state), 766 .base = { 767 .cra_name = "hmac(sha384)", 768 .cra_driver_name = "sha384-hmac-starfive", 769 .cra_priority = 200, 770 .cra_flags = CRYPTO_ALG_ASYNC | 771 CRYPTO_ALG_TYPE_AHASH | 772 CRYPTO_ALG_NEED_FALLBACK, 773 .cra_blocksize = SHA384_BLOCK_SIZE, 774 .cra_ctxsize = sizeof(struct starfive_cryp_ctx), 775 .cra_module = THIS_MODULE, 776 } 777 }, 778 .op = { 779 .do_one_request = starfive_hash_one_request, 780 }, 781 }, { 782 .base.init = starfive_hash_init, 783 .base.update = starfive_hash_update, 784 .base.final = starfive_hash_final, 785 .base.finup = starfive_hash_finup, 786 .base.digest = starfive_hash_digest, 787 .base.export = starfive_hash_export, 788 .base.import = starfive_hash_import, 789 .base.init_tfm = starfive_sha512_init_tfm, 790 .base.exit_tfm = starfive_hash_exit_tfm, 791 .base.halg = { 792 .digestsize = SHA512_DIGEST_SIZE, 793 .statesize = sizeof(struct sha512_state), 794 .base = { 795 .cra_name = "sha512", 796 .cra_driver_name = "sha512-starfive", 797 .cra_priority = 200, 798 .cra_flags = CRYPTO_ALG_ASYNC | 799 CRYPTO_ALG_TYPE_AHASH | 800 CRYPTO_ALG_NEED_FALLBACK, 801 .cra_blocksize = SHA512_BLOCK_SIZE, 802 .cra_ctxsize = sizeof(struct starfive_cryp_ctx), 803 .cra_module = THIS_MODULE, 804 } 805 }, 806 .op = { 807 .do_one_request = starfive_hash_one_request, 808 }, 809 }, { 810 .base.init = starfive_hash_init, 811 .base.update = starfive_hash_update, 812 .base.final = starfive_hash_final, 813 .base.finup = starfive_hash_finup, 814 .base.digest = starfive_hash_digest, 815 .base.export = starfive_hash_export, 816 .base.import = starfive_hash_import, 817 .base.init_tfm = starfive_hmac_sha512_init_tfm, 818 .base.exit_tfm = starfive_hash_exit_tfm, 819 .base.setkey = starfive_hash_setkey, 820 .base.halg = { 821 .digestsize = SHA512_DIGEST_SIZE, 822 .statesize = sizeof(struct sha512_state), 823 .base = { 824 .cra_name = "hmac(sha512)", 825 .cra_driver_name = "sha512-hmac-starfive", 826 .cra_priority = 200, 827 .cra_flags = CRYPTO_ALG_ASYNC | 828 CRYPTO_ALG_TYPE_AHASH | 829 CRYPTO_ALG_NEED_FALLBACK, 830 .cra_blocksize = SHA512_BLOCK_SIZE, 831 .cra_ctxsize = sizeof(struct starfive_cryp_ctx), 832 .cra_module = THIS_MODULE, 833 } 834 }, 835 .op = { 836 .do_one_request = starfive_hash_one_request, 837 }, 838 }, { 839 .base.init = starfive_hash_init, 840 .base.update = starfive_hash_update, 841 .base.final = starfive_hash_final, 842 .base.finup = starfive_hash_finup, 843 .base.digest = starfive_hash_digest, 844 .base.export = starfive_hash_export, 845 .base.import = starfive_hash_import, 846 .base.init_tfm = starfive_sm3_init_tfm, 847 .base.exit_tfm = starfive_hash_exit_tfm, 848 .base.halg = { 849 .digestsize = SM3_DIGEST_SIZE, 850 .statesize = sizeof(struct sm3_state), 851 .base = { 852 .cra_name = "sm3", 853 .cra_driver_name = "sm3-starfive", 854 .cra_priority = 200, 855 .cra_flags = CRYPTO_ALG_ASYNC | 856 CRYPTO_ALG_TYPE_AHASH | 857 CRYPTO_ALG_NEED_FALLBACK, 858 .cra_blocksize = SM3_BLOCK_SIZE, 859 .cra_ctxsize = sizeof(struct starfive_cryp_ctx), 860 .cra_module = THIS_MODULE, 861 } 862 }, 863 .op = { 864 .do_one_request = starfive_hash_one_request, 865 }, 866 }, { 867 .base.init = starfive_hash_init, 868 .base.update = starfive_hash_update, 869 .base.final = starfive_hash_final, 870 .base.finup = starfive_hash_finup, 871 .base.digest = starfive_hash_digest, 872 .base.export = starfive_hash_export, 873 .base.import = starfive_hash_import, 874 .base.init_tfm = starfive_hmac_sm3_init_tfm, 875 .base.exit_tfm = starfive_hash_exit_tfm, 876 .base.setkey = starfive_hash_setkey, 877 .base.halg = { 878 .digestsize = SM3_DIGEST_SIZE, 879 .statesize = sizeof(struct sm3_state), 880 .base = { 881 .cra_name = "hmac(sm3)", 882 .cra_driver_name = "sm3-hmac-starfive", 883 .cra_priority = 200, 884 .cra_flags = CRYPTO_ALG_ASYNC | 885 CRYPTO_ALG_TYPE_AHASH | 886 CRYPTO_ALG_NEED_FALLBACK, 887 .cra_blocksize = SM3_BLOCK_SIZE, 888 .cra_ctxsize = sizeof(struct starfive_cryp_ctx), 889 .cra_module = THIS_MODULE, 890 } 891 }, 892 .op = { 893 .do_one_request = starfive_hash_one_request, 894 }, 895 }, 896 }; 897 898 int starfive_hash_register_algs(void) 899 { 900 return crypto_engine_register_ahashes(algs_sha2_sm3, ARRAY_SIZE(algs_sha2_sm3)); 901 } 902 903 void starfive_hash_unregister_algs(void) 904 { 905 crypto_engine_unregister_ahashes(algs_sha2_sm3, ARRAY_SIZE(algs_sha2_sm3)); 906 } 907