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