Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 
0003 #include <crypto/internal/hash.h>
0004 #include <linux/init.h>
0005 #include <linux/module.h>
0006 #include <linux/xxhash.h>
0007 #include <asm/unaligned.h>
0008 
0009 #define XXHASH64_BLOCK_SIZE 32
0010 #define XXHASH64_DIGEST_SIZE    8
0011 
0012 struct xxhash64_tfm_ctx {
0013     u64 seed;
0014 };
0015 
0016 struct xxhash64_desc_ctx {
0017     struct xxh64_state xxhstate;
0018 };
0019 
0020 static int xxhash64_setkey(struct crypto_shash *tfm, const u8 *key,
0021              unsigned int keylen)
0022 {
0023     struct xxhash64_tfm_ctx *tctx = crypto_shash_ctx(tfm);
0024 
0025     if (keylen != sizeof(tctx->seed))
0026         return -EINVAL;
0027     tctx->seed = get_unaligned_le64(key);
0028     return 0;
0029 }
0030 
0031 static int xxhash64_init(struct shash_desc *desc)
0032 {
0033     struct xxhash64_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm);
0034     struct xxhash64_desc_ctx *dctx = shash_desc_ctx(desc);
0035 
0036     xxh64_reset(&dctx->xxhstate, tctx->seed);
0037 
0038     return 0;
0039 }
0040 
0041 static int xxhash64_update(struct shash_desc *desc, const u8 *data,
0042              unsigned int length)
0043 {
0044     struct xxhash64_desc_ctx *dctx = shash_desc_ctx(desc);
0045 
0046     xxh64_update(&dctx->xxhstate, data, length);
0047 
0048     return 0;
0049 }
0050 
0051 static int xxhash64_final(struct shash_desc *desc, u8 *out)
0052 {
0053     struct xxhash64_desc_ctx *dctx = shash_desc_ctx(desc);
0054 
0055     put_unaligned_le64(xxh64_digest(&dctx->xxhstate), out);
0056 
0057     return 0;
0058 }
0059 
0060 static int xxhash64_digest(struct shash_desc *desc, const u8 *data,
0061              unsigned int length, u8 *out)
0062 {
0063     struct xxhash64_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm);
0064 
0065     put_unaligned_le64(xxh64(data, length, tctx->seed), out);
0066 
0067     return 0;
0068 }
0069 
0070 static struct shash_alg alg = {
0071     .digestsize = XXHASH64_DIGEST_SIZE,
0072     .setkey     = xxhash64_setkey,
0073     .init       = xxhash64_init,
0074     .update     = xxhash64_update,
0075     .final      = xxhash64_final,
0076     .digest     = xxhash64_digest,
0077     .descsize   = sizeof(struct xxhash64_desc_ctx),
0078     .base       = {
0079         .cra_name    = "xxhash64",
0080         .cra_driver_name = "xxhash64-generic",
0081         .cra_priority    = 100,
0082         .cra_flags   = CRYPTO_ALG_OPTIONAL_KEY,
0083         .cra_blocksize   = XXHASH64_BLOCK_SIZE,
0084         .cra_ctxsize     = sizeof(struct xxhash64_tfm_ctx),
0085         .cra_module  = THIS_MODULE,
0086     }
0087 };
0088 
0089 static int __init xxhash_mod_init(void)
0090 {
0091     return crypto_register_shash(&alg);
0092 }
0093 
0094 static void __exit xxhash_mod_fini(void)
0095 {
0096     crypto_unregister_shash(&alg);
0097 }
0098 
0099 subsys_initcall(xxhash_mod_init);
0100 module_exit(xxhash_mod_fini);
0101 
0102 MODULE_AUTHOR("Nikolay Borisov <nborisov@suse.com>");
0103 MODULE_DESCRIPTION("xxhash calculations wrapper for lib/xxhash.c");
0104 MODULE_LICENSE("GPL");
0105 MODULE_ALIAS_CRYPTO("xxhash64");
0106 MODULE_ALIAS_CRYPTO("xxhash64-generic");