File Index
Files and directories
Sign in
FILE

tegra-se-hash.c

File preview with syntax highlighting.

linux-6.19.14/drivers/crypto/tegra/tegra-se-hash.c C
   1// SPDX-License-Identifier: GPL-2.0-only
   2// SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
   3/*
   4 * Crypto driver to handle HASH algorithms using NVIDIA Security Engine.
   5 */
   6
   7#include <linux/clk.h>
   8#include <linux/dma-mapping.h>
   9#include <linux/module.h>
  10#include <linux/of_device.h>
  11#include <linux/platform_device.h>
  12
  13#include <crypto/aes.h>
  14#include <crypto/sha1.h>
  15#include <crypto/sha2.h>
  16#include <crypto/sha3.h>
  17#include <crypto/internal/des.h>
  18#include <crypto/engine.h>
  19#include <crypto/scatterwalk.h>
  20#include <crypto/internal/hash.h>
  21
  22#include "tegra-se.h"
  23
  24struct tegra_sha_ctx {
  25	struct tegra_se *se;
  26	unsigned int alg;
  27	bool fallback;
  28	u32 key_id;
  29	struct crypto_ahash *fallback_tfm;
  30};
  31
  32struct tegra_sha_reqctx {
  33	struct scatterlist *src_sg;
  34	struct tegra_se_datbuf datbuf;
  35	struct tegra_se_datbuf residue;
  36	struct tegra_se_datbuf digest;
  37	struct tegra_se_datbuf intr_res;
  38	unsigned int alg;
  39	unsigned int config;
  40	unsigned int total_len;
  41	unsigned int blk_size;
  42	unsigned int task;
  43	u32 key_id;
  44	u32 result[HASH_RESULT_REG_COUNT];
  45	struct ahash_request fallback_req;
  46};
  47
  48static int tegra_sha_get_config(u32 alg)
  49{
  50	int cfg = 0;
  51
  52	switch (alg) {
  53	case SE_ALG_SHA1:
  54		cfg |= SE_SHA_ENC_ALG_SHA;
  55		cfg |= SE_SHA_ENC_MODE_SHA1;
  56		break;
  57
  58	case SE_ALG_HMAC_SHA224:
  59		cfg |= SE_SHA_ENC_ALG_HMAC;
  60		fallthrough;
  61	case SE_ALG_SHA224:
  62		cfg |= SE_SHA_ENC_ALG_SHA;
  63		cfg |= SE_SHA_ENC_MODE_SHA224;
  64		break;
  65
  66	case SE_ALG_HMAC_SHA256:
  67		cfg |= SE_SHA_ENC_ALG_HMAC;
  68		fallthrough;
  69	case SE_ALG_SHA256:
  70		cfg |= SE_SHA_ENC_ALG_SHA;
  71		cfg |= SE_SHA_ENC_MODE_SHA256;
  72		break;
  73
  74	case SE_ALG_HMAC_SHA384:
  75		cfg |= SE_SHA_ENC_ALG_HMAC;
  76		fallthrough;
  77	case SE_ALG_SHA384:
  78		cfg |= SE_SHA_ENC_ALG_SHA;
  79		cfg |= SE_SHA_ENC_MODE_SHA384;
  80		break;
  81
  82	case SE_ALG_HMAC_SHA512:
  83		cfg |= SE_SHA_ENC_ALG_HMAC;
  84		fallthrough;
  85	case SE_ALG_SHA512:
  86		cfg |= SE_SHA_ENC_ALG_SHA;
  87		cfg |= SE_SHA_ENC_MODE_SHA512;
  88		break;
  89
  90	case SE_ALG_SHA3_224:
  91		cfg |= SE_SHA_ENC_ALG_SHA;
  92		cfg |= SE_SHA_ENC_MODE_SHA3_224;
  93		break;
  94	case SE_ALG_SHA3_256:
  95		cfg |= SE_SHA_ENC_ALG_SHA;
  96		cfg |= SE_SHA_ENC_MODE_SHA3_256;
  97		break;
  98	case SE_ALG_SHA3_384:
  99		cfg |= SE_SHA_ENC_ALG_SHA;
 100		cfg |= SE_SHA_ENC_MODE_SHA3_384;
 101		break;
 102	case SE_ALG_SHA3_512:
 103		cfg |= SE_SHA_ENC_ALG_SHA;
 104		cfg |= SE_SHA_ENC_MODE_SHA3_512;
 105		break;
 106	default:
 107		return -EINVAL;
 108	}
 109
 110	return cfg;
 111}
 112
 113static int tegra_sha_fallback_init(struct ahash_request *req)
 114{
 115	struct tegra_sha_reqctx *rctx = ahash_request_ctx(req);
 116	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
 117	struct tegra_sha_ctx *ctx = crypto_ahash_ctx(tfm);
 118
 119	ahash_request_set_tfm(&rctx->fallback_req, ctx->fallback_tfm);
 120	ahash_request_set_callback(&rctx->fallback_req,
 121				   req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP,
 122				   req->base.complete, req->base.data);
 123
 124	return crypto_ahash_init(&rctx->fallback_req);
 125}
 126
 127static int tegra_sha_fallback_update(struct ahash_request *req)
 128{
 129	struct tegra_sha_reqctx *rctx = ahash_request_ctx(req);
 130	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
 131	struct tegra_sha_ctx *ctx = crypto_ahash_ctx(tfm);
 132
 133	ahash_request_set_tfm(&rctx->fallback_req, ctx->fallback_tfm);
 134	ahash_request_set_callback(&rctx->fallback_req,
 135				   req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP,
 136				   req->base.complete, req->base.data);
 137	ahash_request_set_crypt(&rctx->fallback_req, req->src, NULL, req->nbytes);
 138
 139	return crypto_ahash_update(&rctx->fallback_req);
 140}
 141
 142static int tegra_sha_fallback_final(struct ahash_request *req)
 143{
 144	struct tegra_sha_reqctx *rctx = ahash_request_ctx(req);
 145	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
 146	struct tegra_sha_ctx *ctx = crypto_ahash_ctx(tfm);
 147
 148	ahash_request_set_tfm(&rctx->fallback_req, ctx->fallback_tfm);
 149	ahash_request_set_callback(&rctx->fallback_req,
 150				   req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP,
 151				   req->base.complete, req->base.data);
 152	ahash_request_set_crypt(&rctx->fallback_req, NULL, req->result, 0);
 153
 154	return crypto_ahash_final(&rctx->fallback_req);
 155}
 156
 157static int tegra_sha_fallback_finup(struct ahash_request *req)
 158{
 159	struct tegra_sha_reqctx *rctx = ahash_request_ctx(req);
 160	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
 161	struct tegra_sha_ctx *ctx = crypto_ahash_ctx(tfm);
 162
 163	ahash_request_set_tfm(&rctx->fallback_req, ctx->fallback_tfm);
 164	ahash_request_set_callback(&rctx->fallback_req,
 165				   req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP,
 166				   req->base.complete, req->base.data);
 167	ahash_request_set_crypt(&rctx->fallback_req, req->src, req->result,
 168				req->nbytes);
 169
 170	return crypto_ahash_finup(&rctx->fallback_req);
 171}
 172
 173static int tegra_sha_fallback_digest(struct ahash_request *req)
 174{
 175	struct tegra_sha_reqctx *rctx = ahash_request_ctx(req);
 176	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
 177	struct tegra_sha_ctx *ctx = crypto_ahash_ctx(tfm);
 178
 179	ahash_request_set_tfm(&rctx->fallback_req, ctx->fallback_tfm);
 180	ahash_request_set_callback(&rctx->fallback_req,
 181				   req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP,
 182				   req->base.complete, req->base.data);
 183	ahash_request_set_crypt(&rctx->fallback_req, req->src, req->result,
 184				req->nbytes);
 185
 186	return crypto_ahash_digest(&rctx->fallback_req);
 187}
 188
 189static int tegra_sha_fallback_import(struct ahash_request *req, const void *in)
 190{
 191	struct tegra_sha_reqctx *rctx = ahash_request_ctx(req);
 192	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
 193	struct tegra_sha_ctx *ctx = crypto_ahash_ctx(tfm);
 194
 195	ahash_request_set_tfm(&rctx->fallback_req, ctx->fallback_tfm);
 196	ahash_request_set_callback(&rctx->fallback_req,
 197				   req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP,
 198				   req->base.complete, req->base.data);
 199
 200	return crypto_ahash_import(&rctx->fallback_req, in);
 201}
 202
 203static int tegra_sha_fallback_export(struct ahash_request *req, void *out)
 204{
 205	struct tegra_sha_reqctx *rctx = ahash_request_ctx(req);
 206	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
 207	struct tegra_sha_ctx *ctx = crypto_ahash_ctx(tfm);
 208
 209	ahash_request_set_tfm(&rctx->fallback_req, ctx->fallback_tfm);
 210	ahash_request_set_callback(&rctx->fallback_req,
 211				   req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP,
 212				   req->base.complete, req->base.data);
 213
 214	return crypto_ahash_export(&rctx->fallback_req, out);
 215}
 216
 217static int tegra_se_insert_hash_result(struct tegra_sha_ctx *ctx, u32 *cpuvaddr,
 218				       struct tegra_sha_reqctx *rctx)
 219{
 220	__be32 *res_be = (__be32 *)rctx->intr_res.buf;
 221	u32 *res = (u32 *)rctx->intr_res.buf;
 222	int i = 0, j;
 223
 224	cpuvaddr[i++] = 0;
 225	cpuvaddr[i++] = host1x_opcode_setpayload(HASH_RESULT_REG_COUNT);
 226	cpuvaddr[i++] = se_host1x_opcode_incr_w(SE_SHA_HASH_RESULT);
 227
 228	for (j = 0; j < HASH_RESULT_REG_COUNT; j++) {
 229		int idx = j;
 230
 231		/*
 232		 * The initial, intermediate and final hash value of SHA-384, SHA-512
 233		 * in SHA_HASH_RESULT registers follow the below layout of bytes.
 234		 *
 235		 * +---------------+------------+
 236		 * | HASH_RESULT_0 | B4...B7    |
 237		 * +---------------+------------+
 238		 * | HASH_RESULT_1 | B0...B3    |
 239		 * +---------------+------------+
 240		 * | HASH_RESULT_2 | B12...B15  |
 241		 * +---------------+------------+
 242		 * | HASH_RESULT_3 | B8...B11   |
 243		 * +---------------+------------+
 244		 * |            ......          |
 245		 * +---------------+------------+
 246		 * | HASH_RESULT_14| B60...B63  |
 247		 * +---------------+------------+
 248		 * | HASH_RESULT_15| B56...B59  |
 249		 * +---------------+------------+
 250		 *
 251		 */
 252		if (ctx->alg == SE_ALG_SHA384 || ctx->alg == SE_ALG_SHA512)
 253			idx = (j % 2) ? j - 1 : j + 1;
 254
 255		/* For SHA-1, SHA-224, SHA-256, SHA-384, SHA-512 the initial
 256		 * intermediate and final hash value when stored in
 257		 * SHA_HASH_RESULT registers, the byte order is NOT in
 258		 * little-endian.
 259		 */
 260		if (ctx->alg <= SE_ALG_SHA512)
 261			cpuvaddr[i++] = be32_to_cpu(res_be[idx]);
 262		else
 263			cpuvaddr[i++] = res[idx];
 264	}
 265
 266	return i;
 267}
 268
 269static int tegra_sha_prep_cmd(struct tegra_sha_ctx *ctx, u32 *cpuvaddr,
 270			      struct tegra_sha_reqctx *rctx)
 271{
 272	struct tegra_se *se = ctx->se;
 273	u64 msg_len, msg_left;
 274	int i = 0;
 275
 276	msg_len = rctx->total_len * 8;
 277	msg_left = rctx->datbuf.size * 8;
 278
 279	/*
 280	 * If IN_ADDR_HI_0.SZ > SHA_MSG_LEFT_[0-3] to the HASH engine,
 281	 * HW treats it as the last buffer and process the data.
 282	 * Therefore, add an extra byte to msg_left if it is not the
 283	 * last buffer.
 284	 */
 285	if (rctx->task & SHA_UPDATE) {
 286		msg_left += 8;
 287		msg_len += 8;
 288	}
 289
 290	cpuvaddr[i++] = host1x_opcode_setpayload(8);
 291	cpuvaddr[i++] = se_host1x_opcode_incr_w(SE_SHA_MSG_LENGTH);
 292	cpuvaddr[i++] = lower_32_bits(msg_len);
 293	cpuvaddr[i++] = upper_32_bits(msg_len);
 294	cpuvaddr[i++] = 0;
 295	cpuvaddr[i++] = 0;
 296	cpuvaddr[i++] = lower_32_bits(msg_left);
 297	cpuvaddr[i++] = upper_32_bits(msg_left);
 298	cpuvaddr[i++] = 0;
 299	cpuvaddr[i++] = 0;
 300	cpuvaddr[i++] = host1x_opcode_setpayload(2);
 301	cpuvaddr[i++] = se_host1x_opcode_incr_w(SE_SHA_CFG);
 302	cpuvaddr[i++] = rctx->config;
 303
 304	if (rctx->task & SHA_FIRST) {
 305		cpuvaddr[i++] = SE_SHA_TASK_HASH_INIT;
 306		rctx->task &= ~SHA_FIRST;
 307	} else {
 308		/*
 309		 * If it isn't the first task, program the HASH_RESULT register
 310		 * with the intermediate result from the previous task
 311		 */
 312		i += tegra_se_insert_hash_result(ctx, cpuvaddr + i, rctx);
 313	}
 314
 315	cpuvaddr[i++] = host1x_opcode_setpayload(4);
 316	cpuvaddr[i++] = se_host1x_opcode_incr_w(SE_SHA_IN_ADDR);
 317	cpuvaddr[i++] = rctx->datbuf.addr;
 318	cpuvaddr[i++] = (u32)(SE_ADDR_HI_MSB(upper_32_bits(rctx->datbuf.addr)) |
 319				SE_ADDR_HI_SZ(rctx->datbuf.size));
 320
 321	if (rctx->task & SHA_UPDATE) {
 322		cpuvaddr[i++] = rctx->intr_res.addr;
 323		cpuvaddr[i++] = (u32)(SE_ADDR_HI_MSB(upper_32_bits(rctx->intr_res.addr)) |
 324					SE_ADDR_HI_SZ(rctx->intr_res.size));
 325	} else {
 326		cpuvaddr[i++] = rctx->digest.addr;
 327		cpuvaddr[i++] = (u32)(SE_ADDR_HI_MSB(upper_32_bits(rctx->digest.addr)) |
 328					SE_ADDR_HI_SZ(rctx->digest.size));
 329	}
 330
 331	if (rctx->key_id) {
 332		cpuvaddr[i++] = host1x_opcode_setpayload(1);
 333		cpuvaddr[i++] = se_host1x_opcode_nonincr_w(SE_SHA_CRYPTO_CFG);
 334		cpuvaddr[i++] = SE_AES_KEY_INDEX(rctx->key_id);
 335	}
 336
 337	cpuvaddr[i++] = host1x_opcode_setpayload(1);
 338	cpuvaddr[i++] = se_host1x_opcode_nonincr_w(SE_SHA_OPERATION);
 339	cpuvaddr[i++] = SE_SHA_OP_WRSTALL | SE_SHA_OP_START |
 340			SE_SHA_OP_LASTBUF;
 341	cpuvaddr[i++] = se_host1x_opcode_nonincr(host1x_uclass_incr_syncpt_r(), 1);
 342	cpuvaddr[i++] = host1x_uclass_incr_syncpt_cond_f(1) |
 343			host1x_uclass_incr_syncpt_indx_f(se->syncpt_id);
 344
 345	dev_dbg(se->dev, "msg len %llu msg left %llu sz %zd cfg %#x",
 346		msg_len, msg_left, rctx->datbuf.size, rctx->config);
 347
 348	return i;
 349}
 350
 351static int tegra_sha_do_init(struct ahash_request *req)
 352{
 353	struct tegra_sha_reqctx *rctx = ahash_request_ctx(req);
 354	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
 355	struct tegra_sha_ctx *ctx = crypto_ahash_ctx(tfm);
 356	struct tegra_se *se = ctx->se;
 357
 358	if (ctx->fallback)
 359		return tegra_sha_fallback_init(req);
 360
 361	rctx->total_len = 0;
 362	rctx->datbuf.size = 0;
 363	rctx->residue.size = 0;
 364	rctx->key_id = ctx->key_id;
 365	rctx->task |= SHA_FIRST;
 366	rctx->alg = ctx->alg;
 367	rctx->blk_size = crypto_ahash_blocksize(tfm);
 368	rctx->digest.size = crypto_ahash_digestsize(tfm);
 369
 370	rctx->digest.buf = dma_alloc_coherent(se->dev, rctx->digest.size,
 371					      &rctx->digest.addr, GFP_KERNEL);
 372	if (!rctx->digest.buf)
 373		goto digbuf_fail;
 374
 375	rctx->residue.buf = dma_alloc_coherent(se->dev, rctx->blk_size,
 376					       &rctx->residue.addr, GFP_KERNEL);
 377	if (!rctx->residue.buf)
 378		goto resbuf_fail;
 379
 380	rctx->intr_res.size = HASH_RESULT_REG_COUNT * 4;
 381	rctx->intr_res.buf = dma_alloc_coherent(se->dev, rctx->intr_res.size,
 382						&rctx->intr_res.addr, GFP_KERNEL);
 383	if (!rctx->intr_res.buf)
 384		goto intr_res_fail;
 385
 386	return 0;
 387
 388intr_res_fail:
 389	dma_free_coherent(se->dev, rctx->residue.size, rctx->residue.buf,
 390			  rctx->residue.addr);
 391resbuf_fail:
 392	dma_free_coherent(se->dev, rctx->digest.size, rctx->digest.buf,
 393			  rctx->digest.addr);
 394digbuf_fail:
 395	return -ENOMEM;
 396}
 397
 398static int tegra_sha_do_update(struct ahash_request *req)
 399{
 400	struct tegra_sha_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req));
 401	struct tegra_sha_reqctx *rctx = ahash_request_ctx(req);
 402	struct tegra_se *se = ctx->se;
 403	unsigned int nblks, nresidue, size;
 404	u32 *cpuvaddr = se->cmdbuf->addr;
 405	int ret;
 406
 407	nresidue = (req->nbytes + rctx->residue.size) % rctx->blk_size;
 408	nblks = (req->nbytes + rctx->residue.size) / rctx->blk_size;
 409
 410	/*
 411	 * If nbytes is a multiple of block size and there is no residue,
 412	 * then reserve the last block as residue during final() to process.
 413	 */
 414	if (!nresidue && nblks) {
 415		nresidue = rctx->blk_size;
 416		nblks--;
 417	}
 418
 419	rctx->src_sg = req->src;
 420	rctx->datbuf.size = (req->nbytes + rctx->residue.size) - nresidue;
 421
 422	/*
 423	 * If nbytes are less than a block size, copy it residue and
 424	 * return. The bytes will be processed in final()
 425	 */
 426	if (nblks < 1) {
 427		scatterwalk_map_and_copy(rctx->residue.buf + rctx->residue.size,
 428					 rctx->src_sg, 0, req->nbytes, 0);
 429		rctx->residue.size += req->nbytes;
 430
 431		return 0;
 432	}
 433
 434	rctx->datbuf.buf = dma_alloc_coherent(se->dev, rctx->datbuf.size,
 435					      &rctx->datbuf.addr, GFP_KERNEL);
 436	if (!rctx->datbuf.buf)
 437		return -ENOMEM;
 438
 439	/* Copy the previous residue first */
 440	if (rctx->residue.size)
 441		memcpy(rctx->datbuf.buf, rctx->residue.buf, rctx->residue.size);
 442
 443	scatterwalk_map_and_copy(rctx->datbuf.buf + rctx->residue.size,
 444				 rctx->src_sg, 0, req->nbytes - nresidue, 0);
 445
 446	scatterwalk_map_and_copy(rctx->residue.buf, rctx->src_sg,
 447				 req->nbytes - nresidue, nresidue, 0);
 448
 449	/* Update residue value with the residue after current block */
 450	rctx->residue.size = nresidue;
 451	rctx->total_len += rctx->datbuf.size;
 452
 453	rctx->config = tegra_sha_get_config(rctx->alg) |
 454			SE_SHA_DST_MEMORY;
 455
 456	size = tegra_sha_prep_cmd(ctx, cpuvaddr, rctx);
 457	ret = tegra_se_host1x_submit(se, se->cmdbuf, size);
 458
 459	dma_free_coherent(se->dev, rctx->datbuf.size,
 460			  rctx->datbuf.buf, rctx->datbuf.addr);
 461
 462	return ret;
 463}
 464
 465static int tegra_sha_do_final(struct ahash_request *req)
 466{
 467	struct tegra_sha_reqctx *rctx = ahash_request_ctx(req);
 468	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
 469	struct tegra_sha_ctx *ctx = crypto_ahash_ctx(tfm);
 470	struct tegra_se *se = ctx->se;
 471	u32 *cpuvaddr = se->cmdbuf->addr;
 472	int size, ret = 0;
 473
 474	if (rctx->residue.size) {
 475		rctx->datbuf.buf = dma_alloc_coherent(se->dev, rctx->residue.size,
 476						      &rctx->datbuf.addr, GFP_KERNEL);
 477		if (!rctx->datbuf.buf) {
 478			ret = -ENOMEM;
 479			goto out_free;
 480		}
 481
 482		memcpy(rctx->datbuf.buf, rctx->residue.buf, rctx->residue.size);
 483	}
 484
 485	rctx->datbuf.size = rctx->residue.size;
 486	rctx->total_len += rctx->residue.size;
 487
 488	rctx->config = tegra_sha_get_config(rctx->alg) |
 489		       SE_SHA_DST_MEMORY;
 490
 491	size = tegra_sha_prep_cmd(ctx, cpuvaddr, rctx);
 492	ret = tegra_se_host1x_submit(se, se->cmdbuf, size);
 493	if (ret)
 494		goto out;
 495
 496	/* Copy result */
 497	memcpy(req->result, rctx->digest.buf, rctx->digest.size);
 498
 499out:
 500	if (rctx->residue.size)
 501		dma_free_coherent(se->dev, rctx->datbuf.size,
 502				  rctx->datbuf.buf, rctx->datbuf.addr);
 503out_free:
 504	dma_free_coherent(se->dev, crypto_ahash_blocksize(tfm),
 505			  rctx->residue.buf, rctx->residue.addr);
 506	dma_free_coherent(se->dev, rctx->digest.size, rctx->digest.buf,
 507			  rctx->digest.addr);
 508
 509	dma_free_coherent(se->dev, rctx->intr_res.size, rctx->intr_res.buf,
 510			  rctx->intr_res.addr);
 511
 512	return ret;
 513}
 514
 515static int tegra_sha_do_one_req(struct crypto_engine *engine, void *areq)
 516{
 517	struct ahash_request *req = ahash_request_cast(areq);
 518	struct tegra_sha_reqctx *rctx = ahash_request_ctx(req);
 519	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
 520	struct tegra_sha_ctx *ctx = crypto_ahash_ctx(tfm);
 521	struct tegra_se *se = ctx->se;
 522	int ret = 0;
 523
 524	if (rctx->task & SHA_INIT) {
 525		ret = tegra_sha_do_init(req);
 526		if (ret)
 527			goto out;
 528
 529		rctx->task &= ~SHA_INIT;
 530	}
 531
 532	if (rctx->task & SHA_UPDATE) {
 533		ret = tegra_sha_do_update(req);
 534		if (ret)
 535			goto out;
 536
 537		rctx->task &= ~SHA_UPDATE;
 538	}
 539
 540	if (rctx->task & SHA_FINAL) {
 541		ret = tegra_sha_do_final(req);
 542		if (ret)
 543			goto out;
 544
 545		rctx->task &= ~SHA_FINAL;
 546	}
 547
 548out:
 549	crypto_finalize_hash_request(se->engine, req, ret);
 550
 551	return 0;
 552}
 553
 554static void tegra_sha_init_fallback(struct crypto_ahash *tfm, struct tegra_sha_ctx *ctx,
 555				    const char *algname)
 556{
 557	unsigned int statesize;
 558
 559	ctx->fallback_tfm = crypto_alloc_ahash(algname, 0, CRYPTO_ALG_ASYNC |
 560						CRYPTO_ALG_NEED_FALLBACK);
 561
 562	if (IS_ERR(ctx->fallback_tfm)) {
 563		dev_warn(ctx->se->dev,
 564			 "failed to allocate fallback for %s\n", algname);
 565		ctx->fallback_tfm = NULL;
 566		return;
 567	}
 568
 569	statesize = crypto_ahash_statesize(ctx->fallback_tfm);
 570
 571	if (statesize > sizeof(struct tegra_sha_reqctx))
 572		crypto_ahash_set_statesize(tfm, statesize);
 573
 574	/* Update reqsize if fallback is added */
 575	crypto_ahash_set_reqsize(tfm,
 576				 sizeof(struct tegra_sha_reqctx) +
 577			crypto_ahash_reqsize(ctx->fallback_tfm));
 578}
 579
 580static int tegra_sha_cra_init(struct crypto_tfm *tfm)
 581{
 582	struct tegra_sha_ctx *ctx = crypto_tfm_ctx(tfm);
 583	struct crypto_ahash *ahash_tfm = __crypto_ahash_cast(tfm);
 584	struct ahash_alg *alg = __crypto_ahash_alg(tfm->__crt_alg);
 585	struct tegra_se_alg *se_alg;
 586	const char *algname;
 587	int ret;
 588
 589	algname = crypto_tfm_alg_name(tfm);
 590	se_alg = container_of(alg, struct tegra_se_alg, alg.ahash.base);
 591
 592	crypto_ahash_set_reqsize(ahash_tfm, sizeof(struct tegra_sha_reqctx));
 593
 594	ctx->se = se_alg->se_dev;
 595	ctx->fallback = false;
 596	ctx->key_id = 0;
 597
 598	ret = se_algname_to_algid(algname);
 599	if (ret < 0) {
 600		dev_err(ctx->se->dev, "invalid algorithm\n");
 601		return ret;
 602	}
 603
 604	if (se_alg->alg_base)
 605		tegra_sha_init_fallback(ahash_tfm, ctx, algname);
 606
 607	ctx->alg = ret;
 608
 609	return 0;
 610}
 611
 612static void tegra_sha_cra_exit(struct crypto_tfm *tfm)
 613{
 614	struct tegra_sha_ctx *ctx = crypto_tfm_ctx(tfm);
 615
 616	if (ctx->fallback_tfm)
 617		crypto_free_ahash(ctx->fallback_tfm);
 618
 619	tegra_key_invalidate(ctx->se, ctx->key_id, ctx->alg);
 620}
 621
 622static int tegra_hmac_fallback_setkey(struct tegra_sha_ctx *ctx, const u8 *key,
 623				      unsigned int keylen)
 624{
 625	if (!ctx->fallback_tfm) {
 626		dev_dbg(ctx->se->dev, "invalid key length (%d)\n", keylen);
 627		return -EINVAL;
 628	}
 629
 630	ctx->fallback = true;
 631	return crypto_ahash_setkey(ctx->fallback_tfm, key, keylen);
 632}
 633
 634static int tegra_hmac_setkey(struct crypto_ahash *tfm, const u8 *key,
 635			     unsigned int keylen)
 636{
 637	struct tegra_sha_ctx *ctx = crypto_ahash_ctx(tfm);
 638	int ret;
 639
 640	if (aes_check_keylen(keylen))
 641		return tegra_hmac_fallback_setkey(ctx, key, keylen);
 642
 643	ret = tegra_key_submit(ctx->se, key, keylen, ctx->alg, &ctx->key_id);
 644	if (ret)
 645		return tegra_hmac_fallback_setkey(ctx, key, keylen);
 646
 647	ctx->fallback = false;
 648
 649	return 0;
 650}
 651
 652static int tegra_sha_init(struct ahash_request *req)
 653{
 654	struct tegra_sha_reqctx *rctx = ahash_request_ctx(req);
 655	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
 656	struct tegra_sha_ctx *ctx = crypto_ahash_ctx(tfm);
 657
 658	rctx->task = SHA_INIT;
 659
 660	return crypto_transfer_hash_request_to_engine(ctx->se->engine, req);
 661}
 662
 663static int tegra_sha_update(struct ahash_request *req)
 664{
 665	struct tegra_sha_reqctx *rctx = ahash_request_ctx(req);
 666	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
 667	struct tegra_sha_ctx *ctx = crypto_ahash_ctx(tfm);
 668
 669	if (ctx->fallback)
 670		return tegra_sha_fallback_update(req);
 671
 672	rctx->task |= SHA_UPDATE;
 673
 674	return crypto_transfer_hash_request_to_engine(ctx->se->engine, req);
 675}
 676
 677static int tegra_sha_final(struct ahash_request *req)
 678{
 679	struct tegra_sha_reqctx *rctx = ahash_request_ctx(req);
 680	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
 681	struct tegra_sha_ctx *ctx = crypto_ahash_ctx(tfm);
 682
 683	if (ctx->fallback)
 684		return tegra_sha_fallback_final(req);
 685
 686	rctx->task |= SHA_FINAL;
 687
 688	return crypto_transfer_hash_request_to_engine(ctx->se->engine, req);
 689}
 690
 691static int tegra_sha_finup(struct ahash_request *req)
 692{
 693	struct tegra_sha_reqctx *rctx = ahash_request_ctx(req);
 694	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
 695	struct tegra_sha_ctx *ctx = crypto_ahash_ctx(tfm);
 696
 697	if (ctx->fallback)
 698		return tegra_sha_fallback_finup(req);
 699
 700	rctx->task |= SHA_UPDATE | SHA_FINAL;
 701
 702	return crypto_transfer_hash_request_to_engine(ctx->se->engine, req);
 703}
 704
 705static int tegra_sha_digest(struct ahash_request *req)
 706{
 707	struct tegra_sha_reqctx *rctx = ahash_request_ctx(req);
 708	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
 709	struct tegra_sha_ctx *ctx = crypto_ahash_ctx(tfm);
 710
 711	if (ctx->fallback)
 712		return tegra_sha_fallback_digest(req);
 713
 714	rctx->task |= SHA_INIT | SHA_UPDATE | SHA_FINAL;
 715
 716	return crypto_transfer_hash_request_to_engine(ctx->se->engine, req);
 717}
 718
 719static int tegra_sha_export(struct ahash_request *req, void *out)
 720{
 721	struct tegra_sha_reqctx *rctx = ahash_request_ctx(req);
 722	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
 723	struct tegra_sha_ctx *ctx = crypto_ahash_ctx(tfm);
 724
 725	if (ctx->fallback)
 726		return tegra_sha_fallback_export(req, out);
 727
 728	memcpy(out, rctx, sizeof(*rctx));
 729
 730	return 0;
 731}
 732
 733static int tegra_sha_import(struct ahash_request *req, const void *in)
 734{
 735	struct tegra_sha_reqctx *rctx = ahash_request_ctx(req);
 736	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
 737	struct tegra_sha_ctx *ctx = crypto_ahash_ctx(tfm);
 738
 739	if (ctx->fallback)
 740		return tegra_sha_fallback_import(req, in);
 741
 742	memcpy(rctx, in, sizeof(*rctx));
 743
 744	return 0;
 745}
 746
 747static struct tegra_se_alg tegra_hash_algs[] = {
 748	{
 749		.alg.ahash.op.do_one_request = tegra_sha_do_one_req,
 750		.alg.ahash.base = {
 751			.init = tegra_sha_init,
 752			.update = tegra_sha_update,
 753			.final = tegra_sha_final,
 754			.finup = tegra_sha_finup,
 755			.digest = tegra_sha_digest,
 756			.export = tegra_sha_export,
 757			.import = tegra_sha_import,
 758			.halg.digestsize = SHA1_DIGEST_SIZE,
 759			.halg.statesize = sizeof(struct tegra_sha_reqctx),
 760			.halg.base = {
 761				.cra_name = "sha1",
 762				.cra_driver_name = "tegra-se-sha1",
 763				.cra_priority = 300,
 764				.cra_flags = CRYPTO_ALG_ASYNC,
 765				.cra_blocksize = SHA1_BLOCK_SIZE,
 766				.cra_ctxsize = sizeof(struct tegra_sha_ctx),
 767				.cra_alignmask = 0,
 768				.cra_module = THIS_MODULE,
 769				.cra_init = tegra_sha_cra_init,
 770				.cra_exit = tegra_sha_cra_exit,
 771			}
 772		}
 773	}, {
 774		.alg.ahash.op.do_one_request = tegra_sha_do_one_req,
 775		.alg.ahash.base = {
 776			.init = tegra_sha_init,
 777			.update = tegra_sha_update,
 778			.final = tegra_sha_final,
 779			.finup = tegra_sha_finup,
 780			.digest = tegra_sha_digest,
 781			.export = tegra_sha_export,
 782			.import = tegra_sha_import,
 783			.halg.digestsize = SHA224_DIGEST_SIZE,
 784			.halg.statesize = sizeof(struct tegra_sha_reqctx),
 785			.halg.base = {
 786				.cra_name = "sha224",
 787				.cra_driver_name = "tegra-se-sha224",
 788				.cra_priority = 300,
 789				.cra_flags = CRYPTO_ALG_ASYNC,
 790				.cra_blocksize = SHA224_BLOCK_SIZE,
 791				.cra_ctxsize = sizeof(struct tegra_sha_ctx),
 792				.cra_alignmask = 0,
 793				.cra_module = THIS_MODULE,
 794				.cra_init = tegra_sha_cra_init,
 795				.cra_exit = tegra_sha_cra_exit,
 796			}
 797		}
 798	}, {
 799		.alg.ahash.op.do_one_request = tegra_sha_do_one_req,
 800		.alg.ahash.base = {
 801			.init = tegra_sha_init,
 802			.update = tegra_sha_update,
 803			.final = tegra_sha_final,
 804			.finup = tegra_sha_finup,
 805			.digest = tegra_sha_digest,
 806			.export = tegra_sha_export,
 807			.import = tegra_sha_import,
 808			.halg.digestsize = SHA256_DIGEST_SIZE,
 809			.halg.statesize = sizeof(struct tegra_sha_reqctx),
 810			.halg.base = {
 811				.cra_name = "sha256",
 812				.cra_driver_name = "tegra-se-sha256",
 813				.cra_priority = 300,
 814				.cra_flags = CRYPTO_ALG_ASYNC,
 815				.cra_blocksize = SHA256_BLOCK_SIZE,
 816				.cra_ctxsize = sizeof(struct tegra_sha_ctx),
 817				.cra_alignmask = 0,
 818				.cra_module = THIS_MODULE,
 819				.cra_init = tegra_sha_cra_init,
 820				.cra_exit = tegra_sha_cra_exit,
 821			}
 822		}
 823	}, {
 824		.alg.ahash.op.do_one_request = tegra_sha_do_one_req,
 825		.alg.ahash.base = {
 826			.init = tegra_sha_init,
 827			.update = tegra_sha_update,
 828			.final = tegra_sha_final,
 829			.finup = tegra_sha_finup,
 830			.digest = tegra_sha_digest,
 831			.export = tegra_sha_export,
 832			.import = tegra_sha_import,
 833			.halg.digestsize = SHA384_DIGEST_SIZE,
 834			.halg.statesize = sizeof(struct tegra_sha_reqctx),
 835			.halg.base = {
 836				.cra_name = "sha384",
 837				.cra_driver_name = "tegra-se-sha384",
 838				.cra_priority = 300,
 839				.cra_flags = CRYPTO_ALG_ASYNC,
 840				.cra_blocksize = SHA384_BLOCK_SIZE,
 841				.cra_ctxsize = sizeof(struct tegra_sha_ctx),
 842				.cra_alignmask = 0,
 843				.cra_module = THIS_MODULE,
 844				.cra_init = tegra_sha_cra_init,
 845				.cra_exit = tegra_sha_cra_exit,
 846			}
 847		}
 848	}, {
 849		.alg.ahash.op.do_one_request = tegra_sha_do_one_req,
 850		.alg.ahash.base = {
 851			.init = tegra_sha_init,
 852			.update = tegra_sha_update,
 853			.final = tegra_sha_final,
 854			.finup = tegra_sha_finup,
 855			.digest = tegra_sha_digest,
 856			.export = tegra_sha_export,
 857			.import = tegra_sha_import,
 858			.halg.digestsize = SHA512_DIGEST_SIZE,
 859			.halg.statesize = sizeof(struct tegra_sha_reqctx),
 860			.halg.base = {
 861				.cra_name = "sha512",
 862				.cra_driver_name = "tegra-se-sha512",
 863				.cra_priority = 300,
 864				.cra_flags = CRYPTO_ALG_ASYNC,
 865				.cra_blocksize = SHA512_BLOCK_SIZE,
 866				.cra_ctxsize = sizeof(struct tegra_sha_ctx),
 867				.cra_alignmask = 0,
 868				.cra_module = THIS_MODULE,
 869				.cra_init = tegra_sha_cra_init,
 870				.cra_exit = tegra_sha_cra_exit,
 871			}
 872		}
 873	}, {
 874		.alg.ahash.op.do_one_request = tegra_sha_do_one_req,
 875		.alg.ahash.base = {
 876			.init = tegra_sha_init,
 877			.update = tegra_sha_update,
 878			.final = tegra_sha_final,
 879			.finup = tegra_sha_finup,
 880			.digest = tegra_sha_digest,
 881			.export = tegra_sha_export,
 882			.import = tegra_sha_import,
 883			.halg.digestsize = SHA3_224_DIGEST_SIZE,
 884			.halg.statesize = sizeof(struct tegra_sha_reqctx),
 885			.halg.base = {
 886				.cra_name = "sha3-224",
 887				.cra_driver_name = "tegra-se-sha3-224",
 888				.cra_priority = 300,
 889				.cra_flags = CRYPTO_ALG_ASYNC,
 890				.cra_blocksize = SHA3_224_BLOCK_SIZE,
 891				.cra_ctxsize = sizeof(struct tegra_sha_ctx),
 892				.cra_alignmask = 0,
 893				.cra_module = THIS_MODULE,
 894				.cra_init = tegra_sha_cra_init,
 895				.cra_exit = tegra_sha_cra_exit,
 896			}
 897		}
 898	}, {
 899		.alg.ahash.op.do_one_request = tegra_sha_do_one_req,
 900		.alg.ahash.base = {
 901			.init = tegra_sha_init,
 902			.update = tegra_sha_update,
 903			.final = tegra_sha_final,
 904			.finup = tegra_sha_finup,
 905			.digest = tegra_sha_digest,
 906			.export = tegra_sha_export,
 907			.import = tegra_sha_import,
 908			.halg.digestsize = SHA3_256_DIGEST_SIZE,
 909			.halg.statesize = sizeof(struct tegra_sha_reqctx),
 910			.halg.base = {
 911				.cra_name = "sha3-256",
 912				.cra_driver_name = "tegra-se-sha3-256",
 913				.cra_priority = 300,
 914				.cra_flags = CRYPTO_ALG_ASYNC,
 915				.cra_blocksize = SHA3_256_BLOCK_SIZE,
 916				.cra_ctxsize = sizeof(struct tegra_sha_ctx),
 917				.cra_alignmask = 0,
 918				.cra_module = THIS_MODULE,
 919				.cra_init = tegra_sha_cra_init,
 920				.cra_exit = tegra_sha_cra_exit,
 921			}
 922		}
 923	}, {
 924		.alg.ahash.op.do_one_request = tegra_sha_do_one_req,
 925		.alg.ahash.base = {
 926			.init = tegra_sha_init,
 927			.update = tegra_sha_update,
 928			.final = tegra_sha_final,
 929			.finup = tegra_sha_finup,
 930			.digest = tegra_sha_digest,
 931			.export = tegra_sha_export,
 932			.import = tegra_sha_import,
 933			.halg.digestsize = SHA3_384_DIGEST_SIZE,
 934			.halg.statesize = sizeof(struct tegra_sha_reqctx),
 935			.halg.base = {
 936				.cra_name = "sha3-384",
 937				.cra_driver_name = "tegra-se-sha3-384",
 938				.cra_priority = 300,
 939				.cra_flags = CRYPTO_ALG_ASYNC,
 940				.cra_blocksize = SHA3_384_BLOCK_SIZE,
 941				.cra_ctxsize = sizeof(struct tegra_sha_ctx),
 942				.cra_alignmask = 0,
 943				.cra_module = THIS_MODULE,
 944				.cra_init = tegra_sha_cra_init,
 945				.cra_exit = tegra_sha_cra_exit,
 946			}
 947		}
 948	}, {
 949		.alg.ahash.op.do_one_request = tegra_sha_do_one_req,
 950		.alg.ahash.base = {
 951			.init = tegra_sha_init,
 952			.update = tegra_sha_update,
 953			.final = tegra_sha_final,
 954			.finup = tegra_sha_finup,
 955			.digest = tegra_sha_digest,
 956			.export = tegra_sha_export,
 957			.import = tegra_sha_import,
 958			.halg.digestsize = SHA3_512_DIGEST_SIZE,
 959			.halg.statesize = sizeof(struct tegra_sha_reqctx),
 960			.halg.base = {
 961				.cra_name = "sha3-512",
 962				.cra_driver_name = "tegra-se-sha3-512",
 963				.cra_priority = 300,
 964				.cra_flags = CRYPTO_ALG_ASYNC,
 965				.cra_blocksize = SHA3_512_BLOCK_SIZE,
 966				.cra_ctxsize = sizeof(struct tegra_sha_ctx),
 967				.cra_alignmask = 0,
 968				.cra_module = THIS_MODULE,
 969				.cra_init = tegra_sha_cra_init,
 970				.cra_exit = tegra_sha_cra_exit,
 971			}
 972		}
 973	}, {
 974		.alg_base = "sha224",
 975		.alg.ahash.op.do_one_request = tegra_sha_do_one_req,
 976		.alg.ahash.base = {
 977			.init = tegra_sha_init,
 978			.update = tegra_sha_update,
 979			.final = tegra_sha_final,
 980			.finup = tegra_sha_finup,
 981			.digest = tegra_sha_digest,
 982			.export = tegra_sha_export,
 983			.import = tegra_sha_import,
 984			.setkey = tegra_hmac_setkey,
 985			.halg.digestsize = SHA224_DIGEST_SIZE,
 986			.halg.statesize = sizeof(struct tegra_sha_reqctx),
 987			.halg.base = {
 988				.cra_name = "hmac(sha224)",
 989				.cra_driver_name = "tegra-se-hmac-sha224",
 990				.cra_priority = 300,
 991				.cra_flags = CRYPTO_ALG_ASYNC |
 992					     CRYPTO_ALG_NEED_FALLBACK,
 993				.cra_blocksize = SHA224_BLOCK_SIZE,
 994				.cra_ctxsize = sizeof(struct tegra_sha_ctx),
 995				.cra_alignmask = 0,
 996				.cra_module = THIS_MODULE,
 997				.cra_init = tegra_sha_cra_init,
 998				.cra_exit = tegra_sha_cra_exit,
 999			}
1000		}
1001	}, {
1002		.alg_base = "sha256",
1003		.alg.ahash.op.do_one_request = tegra_sha_do_one_req,
1004		.alg.ahash.base = {
1005			.init = tegra_sha_init,
1006			.update = tegra_sha_update,
1007			.final = tegra_sha_final,
1008			.finup = tegra_sha_finup,
1009			.digest = tegra_sha_digest,
1010			.export = tegra_sha_export,
1011			.import = tegra_sha_import,
1012			.setkey = tegra_hmac_setkey,
1013			.halg.digestsize = SHA256_DIGEST_SIZE,
1014			.halg.statesize = sizeof(struct tegra_sha_reqctx),
1015			.halg.base = {
1016				.cra_name = "hmac(sha256)",
1017				.cra_driver_name = "tegra-se-hmac-sha256",
1018				.cra_priority = 300,
1019				.cra_flags = CRYPTO_ALG_ASYNC |
1020					     CRYPTO_ALG_NEED_FALLBACK,
1021				.cra_blocksize = SHA256_BLOCK_SIZE,
1022				.cra_ctxsize = sizeof(struct tegra_sha_ctx),
1023				.cra_alignmask = 0,
1024				.cra_module = THIS_MODULE,
1025				.cra_init = tegra_sha_cra_init,
1026				.cra_exit = tegra_sha_cra_exit,
1027			}
1028		}
1029	}, {
1030		.alg_base = "sha384",
1031		.alg.ahash.op.do_one_request = tegra_sha_do_one_req,
1032		.alg.ahash.base = {
1033			.init = tegra_sha_init,
1034			.update = tegra_sha_update,
1035			.final = tegra_sha_final,
1036			.finup = tegra_sha_finup,
1037			.digest = tegra_sha_digest,
1038			.export = tegra_sha_export,
1039			.import = tegra_sha_import,
1040			.setkey = tegra_hmac_setkey,
1041			.halg.digestsize = SHA384_DIGEST_SIZE,
1042			.halg.statesize = sizeof(struct tegra_sha_reqctx),
1043			.halg.base = {
1044				.cra_name = "hmac(sha384)",
1045				.cra_driver_name = "tegra-se-hmac-sha384",
1046				.cra_priority = 300,
1047				.cra_flags = CRYPTO_ALG_ASYNC |
1048					     CRYPTO_ALG_NEED_FALLBACK,
1049				.cra_blocksize = SHA384_BLOCK_SIZE,
1050				.cra_ctxsize = sizeof(struct tegra_sha_ctx),
1051				.cra_alignmask = 0,
1052				.cra_module = THIS_MODULE,
1053				.cra_init = tegra_sha_cra_init,
1054				.cra_exit = tegra_sha_cra_exit,
1055			}
1056		}
1057	}, {
1058		.alg_base = "sha512",
1059		.alg.ahash.op.do_one_request = tegra_sha_do_one_req,
1060		.alg.ahash.base = {
1061			.init = tegra_sha_init,
1062			.update = tegra_sha_update,
1063			.final = tegra_sha_final,
1064			.finup = tegra_sha_finup,
1065			.digest = tegra_sha_digest,
1066			.export = tegra_sha_export,
1067			.import = tegra_sha_import,
1068			.setkey = tegra_hmac_setkey,
1069			.halg.digestsize = SHA512_DIGEST_SIZE,
1070			.halg.statesize = sizeof(struct tegra_sha_reqctx),
1071			.halg.base = {
1072				.cra_name = "hmac(sha512)",
1073				.cra_driver_name = "tegra-se-hmac-sha512",
1074				.cra_priority = 300,
1075				.cra_flags = CRYPTO_ALG_ASYNC |
1076					     CRYPTO_ALG_NEED_FALLBACK,
1077				.cra_blocksize = SHA512_BLOCK_SIZE,
1078				.cra_ctxsize = sizeof(struct tegra_sha_ctx),
1079				.cra_alignmask = 0,
1080				.cra_module = THIS_MODULE,
1081				.cra_init = tegra_sha_cra_init,
1082				.cra_exit = tegra_sha_cra_exit,
1083			}
1084		}
1085	}
1086};
1087
1088static int tegra_hash_kac_manifest(u32 user, u32 alg, u32 keylen)
1089{
1090	int manifest;
1091
1092	manifest = SE_KAC_USER_NS;
1093
1094	switch (alg) {
1095	case SE_ALG_HMAC_SHA224:
1096	case SE_ALG_HMAC_SHA256:
1097	case SE_ALG_HMAC_SHA384:
1098	case SE_ALG_HMAC_SHA512:
1099		manifest |= SE_KAC_HMAC;
1100		break;
1101	default:
1102		return -EINVAL;
1103	}
1104
1105	switch (keylen) {
1106	case AES_KEYSIZE_128:
1107		manifest |= SE_KAC_SIZE_128;
1108		break;
1109	case AES_KEYSIZE_192:
1110		manifest |= SE_KAC_SIZE_192;
1111		break;
1112	case AES_KEYSIZE_256:
1113	default:
1114		manifest |= SE_KAC_SIZE_256;
1115		break;
1116	}
1117
1118	return manifest;
1119}
1120
1121int tegra_init_hash(struct tegra_se *se)
1122{
1123	struct ahash_engine_alg *alg;
1124	int i, ret;
1125
1126	se->manifest = tegra_hash_kac_manifest;
1127
1128	for (i = 0; i < ARRAY_SIZE(tegra_hash_algs); i++) {
1129		tegra_hash_algs[i].se_dev = se;
1130		alg = &tegra_hash_algs[i].alg.ahash;
1131
1132		ret = crypto_engine_register_ahash(alg);
1133		if (ret) {
1134			dev_err(se->dev, "failed to register %s\n",
1135				alg->base.halg.base.cra_name);
1136			goto sha_err;
1137		}
1138	}
1139
1140	return 0;
1141
1142sha_err:
1143	while (i--)
1144		crypto_engine_unregister_ahash(&tegra_hash_algs[i].alg.ahash);
1145
1146	return ret;
1147}
1148
1149void tegra_deinit_hash(struct tegra_se *se)
1150{
1151	int i;
1152
1153	for (i = 0; i < ARRAY_SIZE(tegra_hash_algs); i++)
1154		crypto_engine_unregister_ahash(&tegra_hash_algs[i].alg.ahash);
1155}
~/ Read-only file preview.