tegra-se-hash.c 32 KB

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