octeon-sha1.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Cryptographic API.
  4. *
  5. * SHA1 Secure Hash Algorithm.
  6. *
  7. * Adapted for OCTEON by Aaro Koskinen <[email protected]>.
  8. *
  9. * Based on crypto/sha1_generic.c, which is:
  10. *
  11. * Copyright (c) Alan Smithee.
  12. * Copyright (c) Andrew McDonald <[email protected]>
  13. * Copyright (c) Jean-Francois Dive <[email protected]>
  14. */
  15. #include <linux/mm.h>
  16. #include <crypto/sha1.h>
  17. #include <crypto/sha1_base.h>
  18. #include <linux/init.h>
  19. #include <linux/types.h>
  20. #include <linux/module.h>
  21. #include <asm/byteorder.h>
  22. #include <asm/octeon/octeon.h>
  23. #include <crypto/internal/hash.h>
  24. #include "octeon-crypto.h"
  25. /*
  26. * We pass everything as 64-bit. OCTEON can handle misaligned data.
  27. */
  28. static void octeon_sha1_store_hash(struct sha1_state *sctx)
  29. {
  30. u64 *hash = (u64 *)sctx->state;
  31. union {
  32. u32 word[2];
  33. u64 dword;
  34. } hash_tail = { { sctx->state[4], } };
  35. write_octeon_64bit_hash_dword(hash[0], 0);
  36. write_octeon_64bit_hash_dword(hash[1], 1);
  37. write_octeon_64bit_hash_dword(hash_tail.dword, 2);
  38. memzero_explicit(&hash_tail.word[0], sizeof(hash_tail.word[0]));
  39. }
  40. static void octeon_sha1_read_hash(struct sha1_state *sctx)
  41. {
  42. u64 *hash = (u64 *)sctx->state;
  43. union {
  44. u32 word[2];
  45. u64 dword;
  46. } hash_tail;
  47. hash[0] = read_octeon_64bit_hash_dword(0);
  48. hash[1] = read_octeon_64bit_hash_dword(1);
  49. hash_tail.dword = read_octeon_64bit_hash_dword(2);
  50. sctx->state[4] = hash_tail.word[0];
  51. memzero_explicit(&hash_tail.dword, sizeof(hash_tail.dword));
  52. }
  53. static void octeon_sha1_transform(const void *_block)
  54. {
  55. const u64 *block = _block;
  56. write_octeon_64bit_block_dword(block[0], 0);
  57. write_octeon_64bit_block_dword(block[1], 1);
  58. write_octeon_64bit_block_dword(block[2], 2);
  59. write_octeon_64bit_block_dword(block[3], 3);
  60. write_octeon_64bit_block_dword(block[4], 4);
  61. write_octeon_64bit_block_dword(block[5], 5);
  62. write_octeon_64bit_block_dword(block[6], 6);
  63. octeon_sha1_start(block[7]);
  64. }
  65. static void __octeon_sha1_update(struct sha1_state *sctx, const u8 *data,
  66. unsigned int len)
  67. {
  68. unsigned int partial;
  69. unsigned int done;
  70. const u8 *src;
  71. partial = sctx->count % SHA1_BLOCK_SIZE;
  72. sctx->count += len;
  73. done = 0;
  74. src = data;
  75. if ((partial + len) >= SHA1_BLOCK_SIZE) {
  76. if (partial) {
  77. done = -partial;
  78. memcpy(sctx->buffer + partial, data,
  79. done + SHA1_BLOCK_SIZE);
  80. src = sctx->buffer;
  81. }
  82. do {
  83. octeon_sha1_transform(src);
  84. done += SHA1_BLOCK_SIZE;
  85. src = data + done;
  86. } while (done + SHA1_BLOCK_SIZE <= len);
  87. partial = 0;
  88. }
  89. memcpy(sctx->buffer + partial, src, len - done);
  90. }
  91. static int octeon_sha1_update(struct shash_desc *desc, const u8 *data,
  92. unsigned int len)
  93. {
  94. struct sha1_state *sctx = shash_desc_ctx(desc);
  95. struct octeon_cop2_state state;
  96. unsigned long flags;
  97. /*
  98. * Small updates never reach the crypto engine, so the generic sha1 is
  99. * faster because of the heavyweight octeon_crypto_enable() /
  100. * octeon_crypto_disable().
  101. */
  102. if ((sctx->count % SHA1_BLOCK_SIZE) + len < SHA1_BLOCK_SIZE)
  103. return crypto_sha1_update(desc, data, len);
  104. flags = octeon_crypto_enable(&state);
  105. octeon_sha1_store_hash(sctx);
  106. __octeon_sha1_update(sctx, data, len);
  107. octeon_sha1_read_hash(sctx);
  108. octeon_crypto_disable(&state, flags);
  109. return 0;
  110. }
  111. static int octeon_sha1_final(struct shash_desc *desc, u8 *out)
  112. {
  113. struct sha1_state *sctx = shash_desc_ctx(desc);
  114. static const u8 padding[64] = { 0x80, };
  115. struct octeon_cop2_state state;
  116. __be32 *dst = (__be32 *)out;
  117. unsigned int pad_len;
  118. unsigned long flags;
  119. unsigned int index;
  120. __be64 bits;
  121. int i;
  122. /* Save number of bits. */
  123. bits = cpu_to_be64(sctx->count << 3);
  124. /* Pad out to 56 mod 64. */
  125. index = sctx->count & 0x3f;
  126. pad_len = (index < 56) ? (56 - index) : ((64+56) - index);
  127. flags = octeon_crypto_enable(&state);
  128. octeon_sha1_store_hash(sctx);
  129. __octeon_sha1_update(sctx, padding, pad_len);
  130. /* Append length (before padding). */
  131. __octeon_sha1_update(sctx, (const u8 *)&bits, sizeof(bits));
  132. octeon_sha1_read_hash(sctx);
  133. octeon_crypto_disable(&state, flags);
  134. /* Store state in digest */
  135. for (i = 0; i < 5; i++)
  136. dst[i] = cpu_to_be32(sctx->state[i]);
  137. /* Zeroize sensitive information. */
  138. memset(sctx, 0, sizeof(*sctx));
  139. return 0;
  140. }
  141. static int octeon_sha1_export(struct shash_desc *desc, void *out)
  142. {
  143. struct sha1_state *sctx = shash_desc_ctx(desc);
  144. memcpy(out, sctx, sizeof(*sctx));
  145. return 0;
  146. }
  147. static int octeon_sha1_import(struct shash_desc *desc, const void *in)
  148. {
  149. struct sha1_state *sctx = shash_desc_ctx(desc);
  150. memcpy(sctx, in, sizeof(*sctx));
  151. return 0;
  152. }
  153. static struct shash_alg octeon_sha1_alg = {
  154. .digestsize = SHA1_DIGEST_SIZE,
  155. .init = sha1_base_init,
  156. .update = octeon_sha1_update,
  157. .final = octeon_sha1_final,
  158. .export = octeon_sha1_export,
  159. .import = octeon_sha1_import,
  160. .descsize = sizeof(struct sha1_state),
  161. .statesize = sizeof(struct sha1_state),
  162. .base = {
  163. .cra_name = "sha1",
  164. .cra_driver_name= "octeon-sha1",
  165. .cra_priority = OCTEON_CR_OPCODE_PRIORITY,
  166. .cra_blocksize = SHA1_BLOCK_SIZE,
  167. .cra_module = THIS_MODULE,
  168. }
  169. };
  170. static int __init octeon_sha1_mod_init(void)
  171. {
  172. if (!octeon_has_crypto())
  173. return -ENOTSUPP;
  174. return crypto_register_shash(&octeon_sha1_alg);
  175. }
  176. static void __exit octeon_sha1_mod_fini(void)
  177. {
  178. crypto_unregister_shash(&octeon_sha1_alg);
  179. }
  180. module_init(octeon_sha1_mod_init);
  181. module_exit(octeon_sha1_mod_fini);
  182. MODULE_LICENSE("GPL");
  183. MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm (OCTEON)");
  184. MODULE_AUTHOR("Aaro Koskinen <[email protected]>");