sha512_mb.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047
  1. /*
  2. * Multi buffer SHA512 algorithm Glue Code
  3. *
  4. * This file is provided under a dual BSD/GPLv2 license. When using or
  5. * redistributing this file, you may do so under either license.
  6. *
  7. * GPL LICENSE SUMMARY
  8. *
  9. * Copyright(c) 2016 Intel Corporation.
  10. *
  11. * This program is free software; you can redistribute it and/or modify
  12. * it under the terms of version 2 of the GNU General Public License as
  13. * published by the Free Software Foundation.
  14. *
  15. * This program is distributed in the hope that it will be useful, but
  16. * WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  18. * General Public License for more details.
  19. *
  20. * Contact Information:
  21. * Megha Dey <megha.dey@linux.intel.com>
  22. *
  23. * BSD LICENSE
  24. *
  25. * Copyright(c) 2016 Intel Corporation.
  26. *
  27. * Redistribution and use in source and binary forms, with or without
  28. * modification, are permitted provided that the following conditions
  29. * are met:
  30. *
  31. * * Redistributions of source code must retain the above copyright
  32. * notice, this list of conditions and the following disclaimer.
  33. * * Redistributions in binary form must reproduce the above copyright
  34. * notice, this list of conditions and the following disclaimer in
  35. * the documentation and/or other materials provided with the
  36. * distribution.
  37. * * Neither the name of Intel Corporation nor the names of its
  38. * contributors may be used to endorse or promote products derived
  39. * from this software without specific prior written permission.
  40. *
  41. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  42. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  43. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  44. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  45. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  46. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  47. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  48. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  49. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  50. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  51. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  52. */
  53. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  54. #include <crypto/internal/hash.h>
  55. #include <linux/init.h>
  56. #include <linux/module.h>
  57. #include <linux/mm.h>
  58. #include <linux/cryptohash.h>
  59. #include <linux/types.h>
  60. #include <linux/list.h>
  61. #include <crypto/scatterwalk.h>
  62. #include <crypto/sha.h>
  63. #include <crypto/mcryptd.h>
  64. #include <crypto/crypto_wq.h>
  65. #include <asm/byteorder.h>
  66. #include <linux/hardirq.h>
  67. #include <asm/fpu/api.h>
  68. #include "sha512_mb_ctx.h"
  69. #define FLUSH_INTERVAL 1000 /* in usec */
  70. static struct mcryptd_alg_state sha512_mb_alg_state;
  71. struct sha512_mb_ctx {
  72. struct mcryptd_ahash *mcryptd_tfm;
  73. };
  74. static inline struct mcryptd_hash_request_ctx
  75. *cast_hash_to_mcryptd_ctx(struct sha512_hash_ctx *hash_ctx)
  76. {
  77. struct ahash_request *areq;
  78. areq = container_of((void *) hash_ctx, struct ahash_request, __ctx);
  79. return container_of(areq, struct mcryptd_hash_request_ctx, areq);
  80. }
  81. static inline struct ahash_request
  82. *cast_mcryptd_ctx_to_req(struct mcryptd_hash_request_ctx *ctx)
  83. {
  84. return container_of((void *) ctx, struct ahash_request, __ctx);
  85. }
  86. static void req_ctx_init(struct mcryptd_hash_request_ctx *rctx,
  87. struct ahash_request *areq)
  88. {
  89. rctx->flag = HASH_UPDATE;
  90. }
  91. static asmlinkage void (*sha512_job_mgr_init)(struct sha512_mb_mgr *state);
  92. static asmlinkage struct job_sha512* (*sha512_job_mgr_submit)
  93. (struct sha512_mb_mgr *state,
  94. struct job_sha512 *job);
  95. static asmlinkage struct job_sha512* (*sha512_job_mgr_flush)
  96. (struct sha512_mb_mgr *state);
  97. static asmlinkage struct job_sha512* (*sha512_job_mgr_get_comp_job)
  98. (struct sha512_mb_mgr *state);
  99. inline uint32_t sha512_pad(uint8_t padblock[SHA512_BLOCK_SIZE * 2],
  100. uint64_t total_len)
  101. {
  102. uint32_t i = total_len & (SHA512_BLOCK_SIZE - 1);
  103. memset(&padblock[i], 0, SHA512_BLOCK_SIZE);
  104. padblock[i] = 0x80;
  105. i += ((SHA512_BLOCK_SIZE - 1) &
  106. (0 - (total_len + SHA512_PADLENGTHFIELD_SIZE + 1)))
  107. + 1 + SHA512_PADLENGTHFIELD_SIZE;
  108. #if SHA512_PADLENGTHFIELD_SIZE == 16
  109. *((uint64_t *) &padblock[i - 16]) = 0;
  110. #endif
  111. *((uint64_t *) &padblock[i - 8]) = cpu_to_be64(total_len << 3);
  112. /* Number of extra blocks to hash */
  113. return i >> SHA512_LOG2_BLOCK_SIZE;
  114. }
  115. static struct sha512_hash_ctx *sha512_ctx_mgr_resubmit
  116. (struct sha512_ctx_mgr *mgr, struct sha512_hash_ctx *ctx)
  117. {
  118. while (ctx) {
  119. if (ctx->status & HASH_CTX_STS_COMPLETE) {
  120. /* Clear PROCESSING bit */
  121. ctx->status = HASH_CTX_STS_COMPLETE;
  122. return ctx;
  123. }
  124. /*
  125. * If the extra blocks are empty, begin hashing what remains
  126. * in the user's buffer.
  127. */
  128. if (ctx->partial_block_buffer_length == 0 &&
  129. ctx->incoming_buffer_length) {
  130. const void *buffer = ctx->incoming_buffer;
  131. uint32_t len = ctx->incoming_buffer_length;
  132. uint32_t copy_len;
  133. /*
  134. * Only entire blocks can be hashed.
  135. * Copy remainder to extra blocks buffer.
  136. */
  137. copy_len = len & (SHA512_BLOCK_SIZE-1);
  138. if (copy_len) {
  139. len -= copy_len;
  140. memcpy(ctx->partial_block_buffer,
  141. ((const char *) buffer + len),
  142. copy_len);
  143. ctx->partial_block_buffer_length = copy_len;
  144. }
  145. ctx->incoming_buffer_length = 0;
  146. /* len should be a multiple of the block size now */
  147. assert((len % SHA512_BLOCK_SIZE) == 0);
  148. /* Set len to the number of blocks to be hashed */
  149. len >>= SHA512_LOG2_BLOCK_SIZE;
  150. if (len) {
  151. ctx->job.buffer = (uint8_t *) buffer;
  152. ctx->job.len = len;
  153. ctx = (struct sha512_hash_ctx *)
  154. sha512_job_mgr_submit(&mgr->mgr,
  155. &ctx->job);
  156. continue;
  157. }
  158. }
  159. /*
  160. * If the extra blocks are not empty, then we are
  161. * either on the last block(s) or we need more
  162. * user input before continuing.
  163. */
  164. if (ctx->status & HASH_CTX_STS_LAST) {
  165. uint8_t *buf = ctx->partial_block_buffer;
  166. uint32_t n_extra_blocks =
  167. sha512_pad(buf, ctx->total_length);
  168. ctx->status = (HASH_CTX_STS_PROCESSING |
  169. HASH_CTX_STS_COMPLETE);
  170. ctx->job.buffer = buf;
  171. ctx->job.len = (uint32_t) n_extra_blocks;
  172. ctx = (struct sha512_hash_ctx *)
  173. sha512_job_mgr_submit(&mgr->mgr, &ctx->job);
  174. continue;
  175. }
  176. if (ctx)
  177. ctx->status = HASH_CTX_STS_IDLE;
  178. return ctx;
  179. }
  180. return NULL;
  181. }
  182. static struct sha512_hash_ctx
  183. *sha512_ctx_mgr_get_comp_ctx(struct mcryptd_alg_cstate *cstate)
  184. {
  185. /*
  186. * If get_comp_job returns NULL, there are no jobs complete.
  187. * If get_comp_job returns a job, verify that it is safe to return to
  188. * the user.
  189. * If it is not ready, resubmit the job to finish processing.
  190. * If sha512_ctx_mgr_resubmit returned a job, it is ready to be
  191. * returned.
  192. * Otherwise, all jobs currently being managed by the hash_ctx_mgr
  193. * still need processing.
  194. */
  195. struct sha512_ctx_mgr *mgr;
  196. struct sha512_hash_ctx *ctx;
  197. unsigned long flags;
  198. mgr = cstate->mgr;
  199. spin_lock_irqsave(&cstate->work_lock, flags);
  200. ctx = (struct sha512_hash_ctx *)
  201. sha512_job_mgr_get_comp_job(&mgr->mgr);
  202. ctx = sha512_ctx_mgr_resubmit(mgr, ctx);
  203. spin_unlock_irqrestore(&cstate->work_lock, flags);
  204. return ctx;
  205. }
  206. static void sha512_ctx_mgr_init(struct sha512_ctx_mgr *mgr)
  207. {
  208. sha512_job_mgr_init(&mgr->mgr);
  209. }
  210. static struct sha512_hash_ctx
  211. *sha512_ctx_mgr_submit(struct mcryptd_alg_cstate *cstate,
  212. struct sha512_hash_ctx *ctx,
  213. const void *buffer,
  214. uint32_t len,
  215. int flags)
  216. {
  217. struct sha512_ctx_mgr *mgr;
  218. unsigned long irqflags;
  219. mgr = cstate->mgr;
  220. spin_lock_irqsave(&cstate->work_lock, irqflags);
  221. if (flags & ~(HASH_UPDATE | HASH_LAST)) {
  222. /* User should not pass anything other than UPDATE or LAST */
  223. ctx->error = HASH_CTX_ERROR_INVALID_FLAGS;
  224. goto unlock;
  225. }
  226. if (ctx->status & HASH_CTX_STS_PROCESSING) {
  227. /* Cannot submit to a currently processing job. */
  228. ctx->error = HASH_CTX_ERROR_ALREADY_PROCESSING;
  229. goto unlock;
  230. }
  231. if (ctx->status & HASH_CTX_STS_COMPLETE) {
  232. /* Cannot update a finished job. */
  233. ctx->error = HASH_CTX_ERROR_ALREADY_COMPLETED;
  234. goto unlock;
  235. }
  236. /*
  237. * If we made it here, there were no errors during this call to
  238. * submit
  239. */
  240. ctx->error = HASH_CTX_ERROR_NONE;
  241. /* Store buffer ptr info from user */
  242. ctx->incoming_buffer = buffer;
  243. ctx->incoming_buffer_length = len;
  244. /*
  245. * Store the user's request flags and mark this ctx as currently being
  246. * processed.
  247. */
  248. ctx->status = (flags & HASH_LAST) ?
  249. (HASH_CTX_STS_PROCESSING | HASH_CTX_STS_LAST) :
  250. HASH_CTX_STS_PROCESSING;
  251. /* Advance byte counter */
  252. ctx->total_length += len;
  253. /*
  254. * If there is anything currently buffered in the extra blocks,
  255. * append to it until it contains a whole block.
  256. * Or if the user's buffer contains less than a whole block,
  257. * append as much as possible to the extra block.
  258. */
  259. if (ctx->partial_block_buffer_length || len < SHA512_BLOCK_SIZE) {
  260. /* Compute how many bytes to copy from user buffer into extra
  261. * block
  262. */
  263. uint32_t copy_len = SHA512_BLOCK_SIZE -
  264. ctx->partial_block_buffer_length;
  265. if (len < copy_len)
  266. copy_len = len;
  267. if (copy_len) {
  268. /* Copy and update relevant pointers and counters */
  269. memcpy
  270. (&ctx->partial_block_buffer[ctx->partial_block_buffer_length],
  271. buffer, copy_len);
  272. ctx->partial_block_buffer_length += copy_len;
  273. ctx->incoming_buffer = (const void *)
  274. ((const char *)buffer + copy_len);
  275. ctx->incoming_buffer_length = len - copy_len;
  276. }
  277. /* The extra block should never contain more than 1 block
  278. * here
  279. */
  280. assert(ctx->partial_block_buffer_length <= SHA512_BLOCK_SIZE);
  281. /* If the extra block buffer contains exactly 1 block, it can
  282. * be hashed.
  283. */
  284. if (ctx->partial_block_buffer_length >= SHA512_BLOCK_SIZE) {
  285. ctx->partial_block_buffer_length = 0;
  286. ctx->job.buffer = ctx->partial_block_buffer;
  287. ctx->job.len = 1;
  288. ctx = (struct sha512_hash_ctx *)
  289. sha512_job_mgr_submit(&mgr->mgr, &ctx->job);
  290. }
  291. }
  292. ctx = sha512_ctx_mgr_resubmit(mgr, ctx);
  293. unlock:
  294. spin_unlock_irqrestore(&cstate->work_lock, irqflags);
  295. return ctx;
  296. }
  297. static struct sha512_hash_ctx *sha512_ctx_mgr_flush(struct mcryptd_alg_cstate *cstate)
  298. {
  299. struct sha512_ctx_mgr *mgr;
  300. struct sha512_hash_ctx *ctx;
  301. unsigned long flags;
  302. mgr = cstate->mgr;
  303. spin_lock_irqsave(&cstate->work_lock, flags);
  304. while (1) {
  305. ctx = (struct sha512_hash_ctx *)
  306. sha512_job_mgr_flush(&mgr->mgr);
  307. /* If flush returned 0, there are no more jobs in flight. */
  308. if (!ctx)
  309. break;
  310. /*
  311. * If flush returned a job, resubmit the job to finish
  312. * processing.
  313. */
  314. ctx = sha512_ctx_mgr_resubmit(mgr, ctx);
  315. /*
  316. * If sha512_ctx_mgr_resubmit returned a job, it is ready to
  317. * be returned. Otherwise, all jobs currently being managed by
  318. * the sha512_ctx_mgr still need processing. Loop.
  319. */
  320. if (ctx)
  321. break;
  322. }
  323. spin_unlock_irqrestore(&cstate->work_lock, flags);
  324. return ctx;
  325. }
  326. static int sha512_mb_init(struct ahash_request *areq)
  327. {
  328. struct sha512_hash_ctx *sctx = ahash_request_ctx(areq);
  329. hash_ctx_init(sctx);
  330. sctx->job.result_digest[0] = SHA512_H0;
  331. sctx->job.result_digest[1] = SHA512_H1;
  332. sctx->job.result_digest[2] = SHA512_H2;
  333. sctx->job.result_digest[3] = SHA512_H3;
  334. sctx->job.result_digest[4] = SHA512_H4;
  335. sctx->job.result_digest[5] = SHA512_H5;
  336. sctx->job.result_digest[6] = SHA512_H6;
  337. sctx->job.result_digest[7] = SHA512_H7;
  338. sctx->total_length = 0;
  339. sctx->partial_block_buffer_length = 0;
  340. sctx->status = HASH_CTX_STS_IDLE;
  341. return 0;
  342. }
  343. static int sha512_mb_set_results(struct mcryptd_hash_request_ctx *rctx)
  344. {
  345. int i;
  346. struct sha512_hash_ctx *sctx = ahash_request_ctx(&rctx->areq);
  347. __be64 *dst = (__be64 *) rctx->out;
  348. for (i = 0; i < 8; ++i)
  349. dst[i] = cpu_to_be64(sctx->job.result_digest[i]);
  350. return 0;
  351. }
  352. static int sha_finish_walk(struct mcryptd_hash_request_ctx **ret_rctx,
  353. struct mcryptd_alg_cstate *cstate, bool flush)
  354. {
  355. int flag = HASH_UPDATE;
  356. int nbytes, err = 0;
  357. struct mcryptd_hash_request_ctx *rctx = *ret_rctx;
  358. struct sha512_hash_ctx *sha_ctx;
  359. /* more work ? */
  360. while (!(rctx->flag & HASH_DONE)) {
  361. nbytes = crypto_ahash_walk_done(&rctx->walk, 0);
  362. if (nbytes < 0) {
  363. err = nbytes;
  364. goto out;
  365. }
  366. /* check if the walk is done */
  367. if (crypto_ahash_walk_last(&rctx->walk)) {
  368. rctx->flag |= HASH_DONE;
  369. if (rctx->flag & HASH_FINAL)
  370. flag |= HASH_LAST;
  371. }
  372. sha_ctx = (struct sha512_hash_ctx *)
  373. ahash_request_ctx(&rctx->areq);
  374. kernel_fpu_begin();
  375. sha_ctx = sha512_ctx_mgr_submit(cstate, sha_ctx,
  376. rctx->walk.data, nbytes, flag);
  377. if (!sha_ctx) {
  378. if (flush)
  379. sha_ctx = sha512_ctx_mgr_flush(cstate);
  380. }
  381. kernel_fpu_end();
  382. if (sha_ctx)
  383. rctx = cast_hash_to_mcryptd_ctx(sha_ctx);
  384. else {
  385. rctx = NULL;
  386. goto out;
  387. }
  388. }
  389. /* copy the results */
  390. if (rctx->flag & HASH_FINAL)
  391. sha512_mb_set_results(rctx);
  392. out:
  393. *ret_rctx = rctx;
  394. return err;
  395. }
  396. static int sha_complete_job(struct mcryptd_hash_request_ctx *rctx,
  397. struct mcryptd_alg_cstate *cstate,
  398. int err)
  399. {
  400. struct ahash_request *req = cast_mcryptd_ctx_to_req(rctx);
  401. struct sha512_hash_ctx *sha_ctx;
  402. struct mcryptd_hash_request_ctx *req_ctx;
  403. int ret;
  404. unsigned long flags;
  405. /* remove from work list */
  406. spin_lock_irqsave(&cstate->work_lock, flags);
  407. list_del(&rctx->waiter);
  408. spin_unlock_irqrestore(&cstate->work_lock, flags);
  409. if (irqs_disabled())
  410. rctx->complete(&req->base, err);
  411. else {
  412. local_bh_disable();
  413. rctx->complete(&req->base, err);
  414. local_bh_enable();
  415. }
  416. /* check to see if there are other jobs that are done */
  417. sha_ctx = sha512_ctx_mgr_get_comp_ctx(cstate);
  418. while (sha_ctx) {
  419. req_ctx = cast_hash_to_mcryptd_ctx(sha_ctx);
  420. ret = sha_finish_walk(&req_ctx, cstate, false);
  421. if (req_ctx) {
  422. spin_lock_irqsave(&cstate->work_lock, flags);
  423. list_del(&req_ctx->waiter);
  424. spin_unlock_irqrestore(&cstate->work_lock, flags);
  425. req = cast_mcryptd_ctx_to_req(req_ctx);
  426. if (irqs_disabled())
  427. req_ctx->complete(&req->base, ret);
  428. else {
  429. local_bh_disable();
  430. req_ctx->complete(&req->base, ret);
  431. local_bh_enable();
  432. }
  433. }
  434. sha_ctx = sha512_ctx_mgr_get_comp_ctx(cstate);
  435. }
  436. return 0;
  437. }
  438. static void sha512_mb_add_list(struct mcryptd_hash_request_ctx *rctx,
  439. struct mcryptd_alg_cstate *cstate)
  440. {
  441. unsigned long next_flush;
  442. unsigned long delay = usecs_to_jiffies(FLUSH_INTERVAL);
  443. unsigned long flags;
  444. /* initialize tag */
  445. rctx->tag.arrival = jiffies; /* tag the arrival time */
  446. rctx->tag.seq_num = cstate->next_seq_num++;
  447. next_flush = rctx->tag.arrival + delay;
  448. rctx->tag.expire = next_flush;
  449. spin_lock_irqsave(&cstate->work_lock, flags);
  450. list_add_tail(&rctx->waiter, &cstate->work_list);
  451. spin_unlock_irqrestore(&cstate->work_lock, flags);
  452. mcryptd_arm_flusher(cstate, delay);
  453. }
  454. static int sha512_mb_update(struct ahash_request *areq)
  455. {
  456. struct mcryptd_hash_request_ctx *rctx =
  457. container_of(areq, struct mcryptd_hash_request_ctx,
  458. areq);
  459. struct mcryptd_alg_cstate *cstate =
  460. this_cpu_ptr(sha512_mb_alg_state.alg_cstate);
  461. struct ahash_request *req = cast_mcryptd_ctx_to_req(rctx);
  462. struct sha512_hash_ctx *sha_ctx;
  463. int ret = 0, nbytes;
  464. /* sanity check */
  465. if (rctx->tag.cpu != smp_processor_id()) {
  466. pr_err("mcryptd error: cpu clash\n");
  467. goto done;
  468. }
  469. /* need to init context */
  470. req_ctx_init(rctx, areq);
  471. nbytes = crypto_ahash_walk_first(req, &rctx->walk);
  472. if (nbytes < 0) {
  473. ret = nbytes;
  474. goto done;
  475. }
  476. if (crypto_ahash_walk_last(&rctx->walk))
  477. rctx->flag |= HASH_DONE;
  478. /* submit */
  479. sha_ctx = (struct sha512_hash_ctx *) ahash_request_ctx(areq);
  480. sha512_mb_add_list(rctx, cstate);
  481. kernel_fpu_begin();
  482. sha_ctx = sha512_ctx_mgr_submit(cstate, sha_ctx, rctx->walk.data,
  483. nbytes, HASH_UPDATE);
  484. kernel_fpu_end();
  485. /* check if anything is returned */
  486. if (!sha_ctx)
  487. return -EINPROGRESS;
  488. if (sha_ctx->error) {
  489. ret = sha_ctx->error;
  490. rctx = cast_hash_to_mcryptd_ctx(sha_ctx);
  491. goto done;
  492. }
  493. rctx = cast_hash_to_mcryptd_ctx(sha_ctx);
  494. ret = sha_finish_walk(&rctx, cstate, false);
  495. if (!rctx)
  496. return -EINPROGRESS;
  497. done:
  498. sha_complete_job(rctx, cstate, ret);
  499. return ret;
  500. }
  501. static int sha512_mb_finup(struct ahash_request *areq)
  502. {
  503. struct mcryptd_hash_request_ctx *rctx =
  504. container_of(areq, struct mcryptd_hash_request_ctx,
  505. areq);
  506. struct mcryptd_alg_cstate *cstate =
  507. this_cpu_ptr(sha512_mb_alg_state.alg_cstate);
  508. struct ahash_request *req = cast_mcryptd_ctx_to_req(rctx);
  509. struct sha512_hash_ctx *sha_ctx;
  510. int ret = 0, flag = HASH_UPDATE, nbytes;
  511. /* sanity check */
  512. if (rctx->tag.cpu != smp_processor_id()) {
  513. pr_err("mcryptd error: cpu clash\n");
  514. goto done;
  515. }
  516. /* need to init context */
  517. req_ctx_init(rctx, areq);
  518. nbytes = crypto_ahash_walk_first(req, &rctx->walk);
  519. if (nbytes < 0) {
  520. ret = nbytes;
  521. goto done;
  522. }
  523. if (crypto_ahash_walk_last(&rctx->walk)) {
  524. rctx->flag |= HASH_DONE;
  525. flag = HASH_LAST;
  526. }
  527. /* submit */
  528. rctx->flag |= HASH_FINAL;
  529. sha_ctx = (struct sha512_hash_ctx *) ahash_request_ctx(areq);
  530. sha512_mb_add_list(rctx, cstate);
  531. kernel_fpu_begin();
  532. sha_ctx = sha512_ctx_mgr_submit(cstate, sha_ctx, rctx->walk.data,
  533. nbytes, flag);
  534. kernel_fpu_end();
  535. /* check if anything is returned */
  536. if (!sha_ctx)
  537. return -EINPROGRESS;
  538. if (sha_ctx->error) {
  539. ret = sha_ctx->error;
  540. goto done;
  541. }
  542. rctx = cast_hash_to_mcryptd_ctx(sha_ctx);
  543. ret = sha_finish_walk(&rctx, cstate, false);
  544. if (!rctx)
  545. return -EINPROGRESS;
  546. done:
  547. sha_complete_job(rctx, cstate, ret);
  548. return ret;
  549. }
  550. static int sha512_mb_final(struct ahash_request *areq)
  551. {
  552. struct mcryptd_hash_request_ctx *rctx =
  553. container_of(areq, struct mcryptd_hash_request_ctx,
  554. areq);
  555. struct mcryptd_alg_cstate *cstate =
  556. this_cpu_ptr(sha512_mb_alg_state.alg_cstate);
  557. struct sha512_hash_ctx *sha_ctx;
  558. int ret = 0;
  559. u8 data;
  560. /* sanity check */
  561. if (rctx->tag.cpu != smp_processor_id()) {
  562. pr_err("mcryptd error: cpu clash\n");
  563. goto done;
  564. }
  565. /* need to init context */
  566. req_ctx_init(rctx, areq);
  567. rctx->flag |= HASH_DONE | HASH_FINAL;
  568. sha_ctx = (struct sha512_hash_ctx *) ahash_request_ctx(areq);
  569. /* flag HASH_FINAL and 0 data size */
  570. sha512_mb_add_list(rctx, cstate);
  571. kernel_fpu_begin();
  572. sha_ctx = sha512_ctx_mgr_submit(cstate, sha_ctx, &data, 0, HASH_LAST);
  573. kernel_fpu_end();
  574. /* check if anything is returned */
  575. if (!sha_ctx)
  576. return -EINPROGRESS;
  577. if (sha_ctx->error) {
  578. ret = sha_ctx->error;
  579. rctx = cast_hash_to_mcryptd_ctx(sha_ctx);
  580. goto done;
  581. }
  582. rctx = cast_hash_to_mcryptd_ctx(sha_ctx);
  583. ret = sha_finish_walk(&rctx, cstate, false);
  584. if (!rctx)
  585. return -EINPROGRESS;
  586. done:
  587. sha_complete_job(rctx, cstate, ret);
  588. return ret;
  589. }
  590. static int sha512_mb_export(struct ahash_request *areq, void *out)
  591. {
  592. struct sha512_hash_ctx *sctx = ahash_request_ctx(areq);
  593. memcpy(out, sctx, sizeof(*sctx));
  594. return 0;
  595. }
  596. static int sha512_mb_import(struct ahash_request *areq, const void *in)
  597. {
  598. struct sha512_hash_ctx *sctx = ahash_request_ctx(areq);
  599. memcpy(sctx, in, sizeof(*sctx));
  600. return 0;
  601. }
  602. static int sha512_mb_async_init_tfm(struct crypto_tfm *tfm)
  603. {
  604. struct mcryptd_ahash *mcryptd_tfm;
  605. struct sha512_mb_ctx *ctx = crypto_tfm_ctx(tfm);
  606. struct mcryptd_hash_ctx *mctx;
  607. mcryptd_tfm = mcryptd_alloc_ahash("__intel_sha512-mb",
  608. CRYPTO_ALG_INTERNAL,
  609. CRYPTO_ALG_INTERNAL);
  610. if (IS_ERR(mcryptd_tfm))
  611. return PTR_ERR(mcryptd_tfm);
  612. mctx = crypto_ahash_ctx(&mcryptd_tfm->base);
  613. mctx->alg_state = &sha512_mb_alg_state;
  614. ctx->mcryptd_tfm = mcryptd_tfm;
  615. crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
  616. sizeof(struct ahash_request) +
  617. crypto_ahash_reqsize(&mcryptd_tfm->base));
  618. return 0;
  619. }
  620. static void sha512_mb_async_exit_tfm(struct crypto_tfm *tfm)
  621. {
  622. struct sha512_mb_ctx *ctx = crypto_tfm_ctx(tfm);
  623. mcryptd_free_ahash(ctx->mcryptd_tfm);
  624. }
  625. static int sha512_mb_areq_init_tfm(struct crypto_tfm *tfm)
  626. {
  627. crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
  628. sizeof(struct ahash_request) +
  629. sizeof(struct sha512_hash_ctx));
  630. return 0;
  631. }
  632. static void sha512_mb_areq_exit_tfm(struct crypto_tfm *tfm)
  633. {
  634. struct sha512_mb_ctx *ctx = crypto_tfm_ctx(tfm);
  635. mcryptd_free_ahash(ctx->mcryptd_tfm);
  636. }
  637. static struct ahash_alg sha512_mb_areq_alg = {
  638. .init = sha512_mb_init,
  639. .update = sha512_mb_update,
  640. .final = sha512_mb_final,
  641. .finup = sha512_mb_finup,
  642. .export = sha512_mb_export,
  643. .import = sha512_mb_import,
  644. .halg = {
  645. .digestsize = SHA512_DIGEST_SIZE,
  646. .statesize = sizeof(struct sha512_hash_ctx),
  647. .base = {
  648. .cra_name = "__sha512-mb",
  649. .cra_driver_name = "__intel_sha512-mb",
  650. .cra_priority = 100,
  651. /*
  652. * use ASYNC flag as some buffers in multi-buffer
  653. * algo may not have completed before hashing thread
  654. * sleep
  655. */
  656. .cra_flags = CRYPTO_ALG_ASYNC |
  657. CRYPTO_ALG_INTERNAL,
  658. .cra_blocksize = SHA512_BLOCK_SIZE,
  659. .cra_module = THIS_MODULE,
  660. .cra_list = LIST_HEAD_INIT
  661. (sha512_mb_areq_alg.halg.base.cra_list),
  662. .cra_init = sha512_mb_areq_init_tfm,
  663. .cra_exit = sha512_mb_areq_exit_tfm,
  664. .cra_ctxsize = sizeof(struct sha512_hash_ctx),
  665. }
  666. }
  667. };
  668. static int sha512_mb_async_init(struct ahash_request *req)
  669. {
  670. struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
  671. struct sha512_mb_ctx *ctx = crypto_ahash_ctx(tfm);
  672. struct ahash_request *mcryptd_req = ahash_request_ctx(req);
  673. struct mcryptd_ahash *mcryptd_tfm = ctx->mcryptd_tfm;
  674. memcpy(mcryptd_req, req, sizeof(*req));
  675. ahash_request_set_tfm(mcryptd_req, &mcryptd_tfm->base);
  676. return crypto_ahash_init(mcryptd_req);
  677. }
  678. static int sha512_mb_async_update(struct ahash_request *req)
  679. {
  680. struct ahash_request *mcryptd_req = ahash_request_ctx(req);
  681. struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
  682. struct sha512_mb_ctx *ctx = crypto_ahash_ctx(tfm);
  683. struct mcryptd_ahash *mcryptd_tfm = ctx->mcryptd_tfm;
  684. memcpy(mcryptd_req, req, sizeof(*req));
  685. ahash_request_set_tfm(mcryptd_req, &mcryptd_tfm->base);
  686. return crypto_ahash_update(mcryptd_req);
  687. }
  688. static int sha512_mb_async_finup(struct ahash_request *req)
  689. {
  690. struct ahash_request *mcryptd_req = ahash_request_ctx(req);
  691. struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
  692. struct sha512_mb_ctx *ctx = crypto_ahash_ctx(tfm);
  693. struct mcryptd_ahash *mcryptd_tfm = ctx->mcryptd_tfm;
  694. memcpy(mcryptd_req, req, sizeof(*req));
  695. ahash_request_set_tfm(mcryptd_req, &mcryptd_tfm->base);
  696. return crypto_ahash_finup(mcryptd_req);
  697. }
  698. static int sha512_mb_async_final(struct ahash_request *req)
  699. {
  700. struct ahash_request *mcryptd_req = ahash_request_ctx(req);
  701. struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
  702. struct sha512_mb_ctx *ctx = crypto_ahash_ctx(tfm);
  703. struct mcryptd_ahash *mcryptd_tfm = ctx->mcryptd_tfm;
  704. memcpy(mcryptd_req, req, sizeof(*req));
  705. ahash_request_set_tfm(mcryptd_req, &mcryptd_tfm->base);
  706. return crypto_ahash_final(mcryptd_req);
  707. }
  708. static int sha512_mb_async_digest(struct ahash_request *req)
  709. {
  710. struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
  711. struct sha512_mb_ctx *ctx = crypto_ahash_ctx(tfm);
  712. struct ahash_request *mcryptd_req = ahash_request_ctx(req);
  713. struct mcryptd_ahash *mcryptd_tfm = ctx->mcryptd_tfm;
  714. memcpy(mcryptd_req, req, sizeof(*req));
  715. ahash_request_set_tfm(mcryptd_req, &mcryptd_tfm->base);
  716. return crypto_ahash_digest(mcryptd_req);
  717. }
  718. static int sha512_mb_async_export(struct ahash_request *req, void *out)
  719. {
  720. struct ahash_request *mcryptd_req = ahash_request_ctx(req);
  721. struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
  722. struct sha512_mb_ctx *ctx = crypto_ahash_ctx(tfm);
  723. struct mcryptd_ahash *mcryptd_tfm = ctx->mcryptd_tfm;
  724. memcpy(mcryptd_req, req, sizeof(*req));
  725. ahash_request_set_tfm(mcryptd_req, &mcryptd_tfm->base);
  726. return crypto_ahash_export(mcryptd_req, out);
  727. }
  728. static int sha512_mb_async_import(struct ahash_request *req, const void *in)
  729. {
  730. struct ahash_request *mcryptd_req = ahash_request_ctx(req);
  731. struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
  732. struct sha512_mb_ctx *ctx = crypto_ahash_ctx(tfm);
  733. struct mcryptd_ahash *mcryptd_tfm = ctx->mcryptd_tfm;
  734. struct crypto_ahash *child = mcryptd_ahash_child(mcryptd_tfm);
  735. struct mcryptd_hash_request_ctx *rctx;
  736. struct ahash_request *areq;
  737. memcpy(mcryptd_req, req, sizeof(*req));
  738. ahash_request_set_tfm(mcryptd_req, &mcryptd_tfm->base);
  739. rctx = ahash_request_ctx(mcryptd_req);
  740. areq = &rctx->areq;
  741. ahash_request_set_tfm(areq, child);
  742. ahash_request_set_callback(areq, CRYPTO_TFM_REQ_MAY_SLEEP,
  743. rctx->complete, req);
  744. return crypto_ahash_import(mcryptd_req, in);
  745. }
  746. static struct ahash_alg sha512_mb_async_alg = {
  747. .init = sha512_mb_async_init,
  748. .update = sha512_mb_async_update,
  749. .final = sha512_mb_async_final,
  750. .finup = sha512_mb_async_finup,
  751. .digest = sha512_mb_async_digest,
  752. .export = sha512_mb_async_export,
  753. .import = sha512_mb_async_import,
  754. .halg = {
  755. .digestsize = SHA512_DIGEST_SIZE,
  756. .statesize = sizeof(struct sha512_hash_ctx),
  757. .base = {
  758. .cra_name = "sha512",
  759. .cra_driver_name = "sha512_mb",
  760. /*
  761. * Low priority, since with few concurrent hash requests
  762. * this is extremely slow due to the flush delay. Users
  763. * whose workloads would benefit from this can request
  764. * it explicitly by driver name, or can increase its
  765. * priority at runtime using NETLINK_CRYPTO.
  766. */
  767. .cra_priority = 50,
  768. .cra_flags = CRYPTO_ALG_ASYNC,
  769. .cra_blocksize = SHA512_BLOCK_SIZE,
  770. .cra_module = THIS_MODULE,
  771. .cra_list = LIST_HEAD_INIT
  772. (sha512_mb_async_alg.halg.base.cra_list),
  773. .cra_init = sha512_mb_async_init_tfm,
  774. .cra_exit = sha512_mb_async_exit_tfm,
  775. .cra_ctxsize = sizeof(struct sha512_mb_ctx),
  776. .cra_alignmask = 0,
  777. },
  778. },
  779. };
  780. static unsigned long sha512_mb_flusher(struct mcryptd_alg_cstate *cstate)
  781. {
  782. struct mcryptd_hash_request_ctx *rctx;
  783. unsigned long cur_time;
  784. unsigned long next_flush = 0;
  785. struct sha512_hash_ctx *sha_ctx;
  786. cur_time = jiffies;
  787. while (!list_empty(&cstate->work_list)) {
  788. rctx = list_entry(cstate->work_list.next,
  789. struct mcryptd_hash_request_ctx, waiter);
  790. if time_before(cur_time, rctx->tag.expire)
  791. break;
  792. kernel_fpu_begin();
  793. sha_ctx = (struct sha512_hash_ctx *)
  794. sha512_ctx_mgr_flush(cstate);
  795. kernel_fpu_end();
  796. if (!sha_ctx) {
  797. pr_err("sha512_mb error: nothing got flushed for"
  798. " non-empty list\n");
  799. break;
  800. }
  801. rctx = cast_hash_to_mcryptd_ctx(sha_ctx);
  802. sha_finish_walk(&rctx, cstate, true);
  803. sha_complete_job(rctx, cstate, 0);
  804. }
  805. if (!list_empty(&cstate->work_list)) {
  806. rctx = list_entry(cstate->work_list.next,
  807. struct mcryptd_hash_request_ctx, waiter);
  808. /* get the hash context and then flush time */
  809. next_flush = rctx->tag.expire;
  810. mcryptd_arm_flusher(cstate, get_delay(next_flush));
  811. }
  812. return next_flush;
  813. }
  814. static int __init sha512_mb_mod_init(void)
  815. {
  816. int cpu;
  817. int err;
  818. struct mcryptd_alg_cstate *cpu_state;
  819. /* check for dependent cpu features */
  820. if (!boot_cpu_has(X86_FEATURE_AVX2) ||
  821. !boot_cpu_has(X86_FEATURE_BMI2))
  822. return -ENODEV;
  823. /* initialize multibuffer structures */
  824. sha512_mb_alg_state.alg_cstate =
  825. alloc_percpu(struct mcryptd_alg_cstate);
  826. sha512_job_mgr_init = sha512_mb_mgr_init_avx2;
  827. sha512_job_mgr_submit = sha512_mb_mgr_submit_avx2;
  828. sha512_job_mgr_flush = sha512_mb_mgr_flush_avx2;
  829. sha512_job_mgr_get_comp_job = sha512_mb_mgr_get_comp_job_avx2;
  830. if (!sha512_mb_alg_state.alg_cstate)
  831. return -ENOMEM;
  832. for_each_possible_cpu(cpu) {
  833. cpu_state = per_cpu_ptr(sha512_mb_alg_state.alg_cstate, cpu);
  834. cpu_state->next_flush = 0;
  835. cpu_state->next_seq_num = 0;
  836. cpu_state->flusher_engaged = false;
  837. INIT_DELAYED_WORK(&cpu_state->flush, mcryptd_flusher);
  838. cpu_state->cpu = cpu;
  839. cpu_state->alg_state = &sha512_mb_alg_state;
  840. cpu_state->mgr = kzalloc(sizeof(struct sha512_ctx_mgr),
  841. GFP_KERNEL);
  842. if (!cpu_state->mgr)
  843. goto err2;
  844. sha512_ctx_mgr_init(cpu_state->mgr);
  845. INIT_LIST_HEAD(&cpu_state->work_list);
  846. spin_lock_init(&cpu_state->work_lock);
  847. }
  848. sha512_mb_alg_state.flusher = &sha512_mb_flusher;
  849. err = crypto_register_ahash(&sha512_mb_areq_alg);
  850. if (err)
  851. goto err2;
  852. err = crypto_register_ahash(&sha512_mb_async_alg);
  853. if (err)
  854. goto err1;
  855. return 0;
  856. err1:
  857. crypto_unregister_ahash(&sha512_mb_areq_alg);
  858. err2:
  859. for_each_possible_cpu(cpu) {
  860. cpu_state = per_cpu_ptr(sha512_mb_alg_state.alg_cstate, cpu);
  861. kfree(cpu_state->mgr);
  862. }
  863. free_percpu(sha512_mb_alg_state.alg_cstate);
  864. return -ENODEV;
  865. }
  866. static void __exit sha512_mb_mod_fini(void)
  867. {
  868. int cpu;
  869. struct mcryptd_alg_cstate *cpu_state;
  870. crypto_unregister_ahash(&sha512_mb_async_alg);
  871. crypto_unregister_ahash(&sha512_mb_areq_alg);
  872. for_each_possible_cpu(cpu) {
  873. cpu_state = per_cpu_ptr(sha512_mb_alg_state.alg_cstate, cpu);
  874. kfree(cpu_state->mgr);
  875. }
  876. free_percpu(sha512_mb_alg_state.alg_cstate);
  877. }
  878. module_init(sha512_mb_mod_init);
  879. module_exit(sha512_mb_mod_fini);
  880. MODULE_LICENSE("GPL");
  881. MODULE_DESCRIPTION("SHA512 Secure Hash Algorithm, multi buffer accelerated");
  882. MODULE_ALIAS("sha512");