sm3_base.h 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * sm3_base.h - core logic for SM3 implementations
  4. *
  5. * Copyright (C) 2017 ARM Limited or its affiliates.
  6. * Written by Gilad Ben-Yossef <gilad@benyossef.com>
  7. */
  8. #ifndef _CRYPTO_SM3_BASE_H
  9. #define _CRYPTO_SM3_BASE_H
  10. #include <crypto/internal/hash.h>
  11. #include <crypto/sm3.h>
  12. #include <linux/math.h>
  13. #include <linux/module.h>
  14. #include <linux/string.h>
  15. #include <linux/types.h>
  16. #include <linux/unaligned.h>
  17. typedef void (sm3_block_fn)(struct sm3_state *sst, u8 const *src, int blocks);
  18. static inline int sm3_base_init(struct shash_desc *desc)
  19. {
  20. sm3_init(shash_desc_ctx(desc));
  21. return 0;
  22. }
  23. static inline int sm3_base_do_update_blocks(struct shash_desc *desc,
  24. const u8 *data, unsigned int len,
  25. sm3_block_fn *block_fn)
  26. {
  27. unsigned int remain = len - round_down(len, SM3_BLOCK_SIZE);
  28. struct sm3_state *sctx = shash_desc_ctx(desc);
  29. sctx->count += len - remain;
  30. block_fn(sctx, data, len / SM3_BLOCK_SIZE);
  31. return remain;
  32. }
  33. static inline int sm3_base_do_finup(struct shash_desc *desc,
  34. const u8 *src, unsigned int len,
  35. sm3_block_fn *block_fn)
  36. {
  37. unsigned int bit_offset = SM3_BLOCK_SIZE / 8 - 1;
  38. struct sm3_state *sctx = shash_desc_ctx(desc);
  39. union {
  40. __be64 b64[SM3_BLOCK_SIZE / 4];
  41. u8 u8[SM3_BLOCK_SIZE * 2];
  42. } block = {};
  43. if (len >= SM3_BLOCK_SIZE) {
  44. int remain;
  45. remain = sm3_base_do_update_blocks(desc, src, len, block_fn);
  46. src += len - remain;
  47. len = remain;
  48. }
  49. if (len >= bit_offset * 8)
  50. bit_offset += SM3_BLOCK_SIZE / 8;
  51. memcpy(&block, src, len);
  52. block.u8[len] = 0x80;
  53. sctx->count += len;
  54. block.b64[bit_offset] = cpu_to_be64(sctx->count << 3);
  55. block_fn(sctx, block.u8, (bit_offset + 1) * 8 / SM3_BLOCK_SIZE);
  56. memzero_explicit(&block, sizeof(block));
  57. return 0;
  58. }
  59. static inline int sm3_base_finish(struct shash_desc *desc, u8 *out)
  60. {
  61. struct sm3_state *sctx = shash_desc_ctx(desc);
  62. __be32 *digest = (__be32 *)out;
  63. int i;
  64. for (i = 0; i < SM3_DIGEST_SIZE / sizeof(__be32); i++)
  65. put_unaligned_be32(sctx->state[i], digest++);
  66. return 0;
  67. }
  68. #endif /* _CRYPTO_SM3_BASE_H */