xxhash_generic.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <crypto/internal/hash.h>
  3. #include <linux/init.h>
  4. #include <linux/module.h>
  5. #include <linux/xxhash.h>
  6. #include <asm/unaligned.h>
  7. #define XXHASH64_BLOCK_SIZE 32
  8. #define XXHASH64_DIGEST_SIZE 8
  9. struct xxhash64_tfm_ctx {
  10. u64 seed;
  11. };
  12. struct xxhash64_desc_ctx {
  13. struct xxh64_state xxhstate;
  14. };
  15. static int xxhash64_setkey(struct crypto_shash *tfm, const u8 *key,
  16. unsigned int keylen)
  17. {
  18. struct xxhash64_tfm_ctx *tctx = crypto_shash_ctx(tfm);
  19. if (keylen != sizeof(tctx->seed))
  20. return -EINVAL;
  21. tctx->seed = get_unaligned_le64(key);
  22. return 0;
  23. }
  24. static int xxhash64_init(struct shash_desc *desc)
  25. {
  26. struct xxhash64_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm);
  27. struct xxhash64_desc_ctx *dctx = shash_desc_ctx(desc);
  28. xxh64_reset(&dctx->xxhstate, tctx->seed);
  29. return 0;
  30. }
  31. static int xxhash64_update(struct shash_desc *desc, const u8 *data,
  32. unsigned int length)
  33. {
  34. struct xxhash64_desc_ctx *dctx = shash_desc_ctx(desc);
  35. xxh64_update(&dctx->xxhstate, data, length);
  36. return 0;
  37. }
  38. static int xxhash64_final(struct shash_desc *desc, u8 *out)
  39. {
  40. struct xxhash64_desc_ctx *dctx = shash_desc_ctx(desc);
  41. put_unaligned_le64(xxh64_digest(&dctx->xxhstate), out);
  42. return 0;
  43. }
  44. static int xxhash64_digest(struct shash_desc *desc, const u8 *data,
  45. unsigned int length, u8 *out)
  46. {
  47. struct xxhash64_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm);
  48. put_unaligned_le64(xxh64(data, length, tctx->seed), out);
  49. return 0;
  50. }
  51. static struct shash_alg alg = {
  52. .digestsize = XXHASH64_DIGEST_SIZE,
  53. .setkey = xxhash64_setkey,
  54. .init = xxhash64_init,
  55. .update = xxhash64_update,
  56. .final = xxhash64_final,
  57. .digest = xxhash64_digest,
  58. .descsize = sizeof(struct xxhash64_desc_ctx),
  59. .base = {
  60. .cra_name = "xxhash64",
  61. .cra_driver_name = "xxhash64-generic",
  62. .cra_priority = 100,
  63. .cra_flags = CRYPTO_ALG_OPTIONAL_KEY,
  64. .cra_blocksize = XXHASH64_BLOCK_SIZE,
  65. .cra_ctxsize = sizeof(struct xxhash64_tfm_ctx),
  66. .cra_module = THIS_MODULE,
  67. }
  68. };
  69. static int __init xxhash_mod_init(void)
  70. {
  71. return crypto_register_shash(&alg);
  72. }
  73. static void __exit xxhash_mod_fini(void)
  74. {
  75. crypto_unregister_shash(&alg);
  76. }
  77. subsys_initcall(xxhash_mod_init);
  78. module_exit(xxhash_mod_fini);
  79. MODULE_AUTHOR("Nikolay Borisov <nborisov@suse.com>");
  80. MODULE_DESCRIPTION("xxhash calculations wrapper for lib/xxhash.c");
  81. MODULE_LICENSE("GPL");
  82. MODULE_ALIAS_CRYPTO("xxhash64");
  83. MODULE_ALIAS_CRYPTO("xxhash64-generic");