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