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 ctx->enginectx.op.prepare_request = NULL; 438 ctx->enginectx.op.unprepare_request = NULL; 439 440 return 0; 441 } 442 443 static void starfive_hash_exit_tfm(struct crypto_ahash *hash) 444 { 445 struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(hash); 446 447 crypto_free_ahash(ctx->ahash_fbk); 448 449 ctx->ahash_fbk = NULL; 450 ctx->enginectx.op.do_one_request = NULL; 451 ctx->enginectx.op.prepare_request = NULL; 452 ctx->enginectx.op.unprepare_request = NULL; 453 } 454 455 static int starfive_hash_long_setkey(struct starfive_cryp_ctx *ctx, 456 const u8 *key, unsigned int keylen, 457 const char *alg_name) 458 { 459 struct crypto_wait wait; 460 struct ahash_request *req; 461 struct scatterlist sg; 462 struct crypto_ahash *ahash_tfm; 463 u8 *buf; 464 int ret; 465 466 ahash_tfm = crypto_alloc_ahash(alg_name, 0, 0); 467 if (IS_ERR(ahash_tfm)) 468 return PTR_ERR(ahash_tfm); 469 470 req = ahash_request_alloc(ahash_tfm, GFP_KERNEL); 471 if (!req) { 472 ret = -ENOMEM; 473 goto err_free_ahash; 474 } 475 476 crypto_init_wait(&wait); 477 ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 478 crypto_req_done, &wait); 479 crypto_ahash_clear_flags(ahash_tfm, ~0); 480 481 buf = kzalloc(keylen + STARFIVE_HASH_BUFLEN, GFP_KERNEL); 482 if (!buf) { 483 ret = -ENOMEM; 484 goto err_free_req; 485 } 486 487 memcpy(buf, key, keylen); 488 sg_init_one(&sg, buf, keylen); 489 ahash_request_set_crypt(req, &sg, ctx->key, keylen); 490 491 ret = crypto_wait_req(crypto_ahash_digest(req), &wait); 492 493 kfree(buf); 494 err_free_req: 495 ahash_request_free(req); 496 err_free_ahash: 497 crypto_free_ahash(ahash_tfm); 498 return ret; 499 } 500 501 static int starfive_hash_setkey(struct crypto_ahash *hash, 502 const u8 *key, unsigned int keylen) 503 { 504 struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(hash); 505 unsigned int digestsize = crypto_ahash_digestsize(hash); 506 unsigned int blocksize = crypto_ahash_blocksize(hash); 507 const char *alg_name; 508 509 crypto_ahash_setkey(ctx->ahash_fbk, key, keylen); 510 511 if (keylen <= blocksize) { 512 memcpy(ctx->key, key, keylen); 513 ctx->keylen = keylen; 514 return 0; 515 } 516 517 ctx->keylen = digestsize; 518 519 switch (digestsize) { 520 case SHA224_DIGEST_SIZE: 521 alg_name = "sha224-starfive"; 522 break; 523 case SHA256_DIGEST_SIZE: 524 if (ctx->hash_mode == STARFIVE_HASH_SM3) 525 alg_name = "sm3-starfive"; 526 else 527 alg_name = "sha256-starfive"; 528 break; 529 case SHA384_DIGEST_SIZE: 530 alg_name = "sha384-starfive"; 531 break; 532 case SHA512_DIGEST_SIZE: 533 alg_name = "sha512-starfive"; 534 break; 535 default: 536 return -EINVAL; 537 } 538 539 return starfive_hash_long_setkey(ctx, key, keylen, alg_name); 540 } 541 542 static int starfive_sha224_init_tfm(struct crypto_ahash *hash) 543 { 544 return starfive_hash_init_tfm(hash, "sha224-generic", 545 STARFIVE_HASH_SHA224); 546 } 547 548 static int starfive_sha256_init_tfm(struct crypto_ahash *hash) 549 { 550 return starfive_hash_init_tfm(hash, "sha256-generic", 551 STARFIVE_HASH_SHA256); 552 } 553 554 static int starfive_sha384_init_tfm(struct crypto_ahash *hash) 555 { 556 return starfive_hash_init_tfm(hash, "sha384-generic", 557 STARFIVE_HASH_SHA384); 558 } 559 560 static int starfive_sha512_init_tfm(struct crypto_ahash *hash) 561 { 562 return starfive_hash_init_tfm(hash, "sha512-generic", 563 STARFIVE_HASH_SHA512); 564 } 565 566 static int starfive_sm3_init_tfm(struct crypto_ahash *hash) 567 { 568 return starfive_hash_init_tfm(hash, "sm3-generic", 569 STARFIVE_HASH_SM3); 570 } 571 572 static int starfive_hmac_sha224_init_tfm(struct crypto_ahash *hash) 573 { 574 struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(hash); 575 576 ctx->is_hmac = true; 577 578 return starfive_hash_init_tfm(hash, "hmac(sha224-generic)", 579 STARFIVE_HASH_SHA224); 580 } 581 582 static int starfive_hmac_sha256_init_tfm(struct crypto_ahash *hash) 583 { 584 struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(hash); 585 586 ctx->is_hmac = true; 587 588 return starfive_hash_init_tfm(hash, "hmac(sha256-generic)", 589 STARFIVE_HASH_SHA256); 590 } 591 592 static int starfive_hmac_sha384_init_tfm(struct crypto_ahash *hash) 593 { 594 struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(hash); 595 596 ctx->is_hmac = true; 597 598 return starfive_hash_init_tfm(hash, "hmac(sha384-generic)", 599 STARFIVE_HASH_SHA384); 600 } 601 602 static int starfive_hmac_sha512_init_tfm(struct crypto_ahash *hash) 603 { 604 struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(hash); 605 606 ctx->is_hmac = true; 607 608 return starfive_hash_init_tfm(hash, "hmac(sha512-generic)", 609 STARFIVE_HASH_SHA512); 610 } 611 612 static int starfive_hmac_sm3_init_tfm(struct crypto_ahash *hash) 613 { 614 struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(hash); 615 616 ctx->is_hmac = true; 617 618 return starfive_hash_init_tfm(hash, "hmac(sm3-generic)", 619 STARFIVE_HASH_SM3); 620 } 621 622 static struct ahash_alg algs_sha2_sm3[] = { 623 { 624 .init = starfive_hash_init, 625 .update = starfive_hash_update, 626 .final = starfive_hash_final, 627 .finup = starfive_hash_finup, 628 .digest = starfive_hash_digest, 629 .export = starfive_hash_export, 630 .import = starfive_hash_import, 631 .init_tfm = starfive_sha224_init_tfm, 632 .exit_tfm = starfive_hash_exit_tfm, 633 .halg = { 634 .digestsize = SHA224_DIGEST_SIZE, 635 .statesize = sizeof(struct sha256_state), 636 .base = { 637 .cra_name = "sha224", 638 .cra_driver_name = "sha224-starfive", 639 .cra_priority = 200, 640 .cra_flags = CRYPTO_ALG_ASYNC | 641 CRYPTO_ALG_TYPE_AHASH | 642 CRYPTO_ALG_NEED_FALLBACK, 643 .cra_blocksize = SHA224_BLOCK_SIZE, 644 .cra_ctxsize = sizeof(struct starfive_cryp_ctx), 645 .cra_alignmask = 3, 646 .cra_module = THIS_MODULE, 647 } 648 } 649 }, { 650 .init = starfive_hash_init, 651 .update = starfive_hash_update, 652 .final = starfive_hash_final, 653 .finup = starfive_hash_finup, 654 .digest = starfive_hash_digest, 655 .export = starfive_hash_export, 656 .import = starfive_hash_import, 657 .init_tfm = starfive_hmac_sha224_init_tfm, 658 .exit_tfm = starfive_hash_exit_tfm, 659 .setkey = starfive_hash_setkey, 660 .halg = { 661 .digestsize = SHA224_DIGEST_SIZE, 662 .statesize = sizeof(struct sha256_state), 663 .base = { 664 .cra_name = "hmac(sha224)", 665 .cra_driver_name = "sha224-hmac-starfive", 666 .cra_priority = 200, 667 .cra_flags = CRYPTO_ALG_ASYNC | 668 CRYPTO_ALG_TYPE_AHASH | 669 CRYPTO_ALG_NEED_FALLBACK, 670 .cra_blocksize = SHA224_BLOCK_SIZE, 671 .cra_ctxsize = sizeof(struct starfive_cryp_ctx), 672 .cra_alignmask = 3, 673 .cra_module = THIS_MODULE, 674 } 675 } 676 }, { 677 .init = starfive_hash_init, 678 .update = starfive_hash_update, 679 .final = starfive_hash_final, 680 .finup = starfive_hash_finup, 681 .digest = starfive_hash_digest, 682 .export = starfive_hash_export, 683 .import = starfive_hash_import, 684 .init_tfm = starfive_sha256_init_tfm, 685 .exit_tfm = starfive_hash_exit_tfm, 686 .halg = { 687 .digestsize = SHA256_DIGEST_SIZE, 688 .statesize = sizeof(struct sha256_state), 689 .base = { 690 .cra_name = "sha256", 691 .cra_driver_name = "sha256-starfive", 692 .cra_priority = 200, 693 .cra_flags = CRYPTO_ALG_ASYNC | 694 CRYPTO_ALG_TYPE_AHASH | 695 CRYPTO_ALG_NEED_FALLBACK, 696 .cra_blocksize = SHA256_BLOCK_SIZE, 697 .cra_ctxsize = sizeof(struct starfive_cryp_ctx), 698 .cra_alignmask = 3, 699 .cra_module = THIS_MODULE, 700 } 701 } 702 }, { 703 .init = starfive_hash_init, 704 .update = starfive_hash_update, 705 .final = starfive_hash_final, 706 .finup = starfive_hash_finup, 707 .digest = starfive_hash_digest, 708 .export = starfive_hash_export, 709 .import = starfive_hash_import, 710 .init_tfm = starfive_hmac_sha256_init_tfm, 711 .exit_tfm = starfive_hash_exit_tfm, 712 .setkey = starfive_hash_setkey, 713 .halg = { 714 .digestsize = SHA256_DIGEST_SIZE, 715 .statesize = sizeof(struct sha256_state), 716 .base = { 717 .cra_name = "hmac(sha256)", 718 .cra_driver_name = "sha256-hmac-starfive", 719 .cra_priority = 200, 720 .cra_flags = CRYPTO_ALG_ASYNC | 721 CRYPTO_ALG_TYPE_AHASH | 722 CRYPTO_ALG_NEED_FALLBACK, 723 .cra_blocksize = SHA256_BLOCK_SIZE, 724 .cra_ctxsize = sizeof(struct starfive_cryp_ctx), 725 .cra_alignmask = 3, 726 .cra_module = THIS_MODULE, 727 } 728 } 729 }, { 730 .init = starfive_hash_init, 731 .update = starfive_hash_update, 732 .final = starfive_hash_final, 733 .finup = starfive_hash_finup, 734 .digest = starfive_hash_digest, 735 .export = starfive_hash_export, 736 .import = starfive_hash_import, 737 .init_tfm = starfive_sha384_init_tfm, 738 .exit_tfm = starfive_hash_exit_tfm, 739 .halg = { 740 .digestsize = SHA384_DIGEST_SIZE, 741 .statesize = sizeof(struct sha512_state), 742 .base = { 743 .cra_name = "sha384", 744 .cra_driver_name = "sha384-starfive", 745 .cra_priority = 200, 746 .cra_flags = CRYPTO_ALG_ASYNC | 747 CRYPTO_ALG_TYPE_AHASH | 748 CRYPTO_ALG_NEED_FALLBACK, 749 .cra_blocksize = SHA384_BLOCK_SIZE, 750 .cra_ctxsize = sizeof(struct starfive_cryp_ctx), 751 .cra_alignmask = 3, 752 .cra_module = THIS_MODULE, 753 } 754 } 755 }, { 756 .init = starfive_hash_init, 757 .update = starfive_hash_update, 758 .final = starfive_hash_final, 759 .finup = starfive_hash_finup, 760 .digest = starfive_hash_digest, 761 .export = starfive_hash_export, 762 .import = starfive_hash_import, 763 .init_tfm = starfive_hmac_sha384_init_tfm, 764 .exit_tfm = starfive_hash_exit_tfm, 765 .setkey = starfive_hash_setkey, 766 .halg = { 767 .digestsize = SHA384_DIGEST_SIZE, 768 .statesize = sizeof(struct sha512_state), 769 .base = { 770 .cra_name = "hmac(sha384)", 771 .cra_driver_name = "sha384-hmac-starfive", 772 .cra_priority = 200, 773 .cra_flags = CRYPTO_ALG_ASYNC | 774 CRYPTO_ALG_TYPE_AHASH | 775 CRYPTO_ALG_NEED_FALLBACK, 776 .cra_blocksize = SHA384_BLOCK_SIZE, 777 .cra_ctxsize = sizeof(struct starfive_cryp_ctx), 778 .cra_alignmask = 3, 779 .cra_module = THIS_MODULE, 780 } 781 } 782 }, { 783 .init = starfive_hash_init, 784 .update = starfive_hash_update, 785 .final = starfive_hash_final, 786 .finup = starfive_hash_finup, 787 .digest = starfive_hash_digest, 788 .export = starfive_hash_export, 789 .import = starfive_hash_import, 790 .init_tfm = starfive_sha512_init_tfm, 791 .exit_tfm = starfive_hash_exit_tfm, 792 .halg = { 793 .digestsize = SHA512_DIGEST_SIZE, 794 .statesize = sizeof(struct sha512_state), 795 .base = { 796 .cra_name = "sha512", 797 .cra_driver_name = "sha512-starfive", 798 .cra_priority = 200, 799 .cra_flags = CRYPTO_ALG_ASYNC | 800 CRYPTO_ALG_TYPE_AHASH | 801 CRYPTO_ALG_NEED_FALLBACK, 802 .cra_blocksize = SHA512_BLOCK_SIZE, 803 .cra_ctxsize = sizeof(struct starfive_cryp_ctx), 804 .cra_alignmask = 3, 805 .cra_module = THIS_MODULE, 806 } 807 } 808 }, { 809 .init = starfive_hash_init, 810 .update = starfive_hash_update, 811 .final = starfive_hash_final, 812 .finup = starfive_hash_finup, 813 .digest = starfive_hash_digest, 814 .export = starfive_hash_export, 815 .import = starfive_hash_import, 816 .init_tfm = starfive_hmac_sha512_init_tfm, 817 .exit_tfm = starfive_hash_exit_tfm, 818 .setkey = starfive_hash_setkey, 819 .halg = { 820 .digestsize = SHA512_DIGEST_SIZE, 821 .statesize = sizeof(struct sha512_state), 822 .base = { 823 .cra_name = "hmac(sha512)", 824 .cra_driver_name = "sha512-hmac-starfive", 825 .cra_priority = 200, 826 .cra_flags = CRYPTO_ALG_ASYNC | 827 CRYPTO_ALG_TYPE_AHASH | 828 CRYPTO_ALG_NEED_FALLBACK, 829 .cra_blocksize = SHA512_BLOCK_SIZE, 830 .cra_ctxsize = sizeof(struct starfive_cryp_ctx), 831 .cra_alignmask = 3, 832 .cra_module = THIS_MODULE, 833 } 834 } 835 }, { 836 .init = starfive_hash_init, 837 .update = starfive_hash_update, 838 .final = starfive_hash_final, 839 .finup = starfive_hash_finup, 840 .digest = starfive_hash_digest, 841 .export = starfive_hash_export, 842 .import = starfive_hash_import, 843 .init_tfm = starfive_sm3_init_tfm, 844 .exit_tfm = starfive_hash_exit_tfm, 845 .halg = { 846 .digestsize = SM3_DIGEST_SIZE, 847 .statesize = sizeof(struct sm3_state), 848 .base = { 849 .cra_name = "sm3", 850 .cra_driver_name = "sm3-starfive", 851 .cra_priority = 200, 852 .cra_flags = CRYPTO_ALG_ASYNC | 853 CRYPTO_ALG_TYPE_AHASH | 854 CRYPTO_ALG_NEED_FALLBACK, 855 .cra_blocksize = SM3_BLOCK_SIZE, 856 .cra_ctxsize = sizeof(struct starfive_cryp_ctx), 857 .cra_alignmask = 3, 858 .cra_module = THIS_MODULE, 859 } 860 } 861 }, { 862 .init = starfive_hash_init, 863 .update = starfive_hash_update, 864 .final = starfive_hash_final, 865 .finup = starfive_hash_finup, 866 .digest = starfive_hash_digest, 867 .export = starfive_hash_export, 868 .import = starfive_hash_import, 869 .init_tfm = starfive_hmac_sm3_init_tfm, 870 .exit_tfm = starfive_hash_exit_tfm, 871 .setkey = starfive_hash_setkey, 872 .halg = { 873 .digestsize = SM3_DIGEST_SIZE, 874 .statesize = sizeof(struct sm3_state), 875 .base = { 876 .cra_name = "hmac(sm3)", 877 .cra_driver_name = "sm3-hmac-starfive", 878 .cra_priority = 200, 879 .cra_flags = CRYPTO_ALG_ASYNC | 880 CRYPTO_ALG_TYPE_AHASH | 881 CRYPTO_ALG_NEED_FALLBACK, 882 .cra_blocksize = SM3_BLOCK_SIZE, 883 .cra_ctxsize = sizeof(struct starfive_cryp_ctx), 884 .cra_alignmask = 3, 885 .cra_module = THIS_MODULE, 886 } 887 } 888 }, 889 }; 890 891 int starfive_hash_register_algs(void) 892 { 893 return crypto_register_ahashes(algs_sha2_sm3, ARRAY_SIZE(algs_sha2_sm3)); 894 } 895 896 void starfive_hash_unregister_algs(void) 897 { 898 crypto_unregister_ahashes(algs_sha2_sm3, ARRAY_SIZE(algs_sha2_sm3)); 899 } 900