1*f3813f4bSKeith Busch // SPDX-License-Identifier: GPL-2.0-only
2*f3813f4bSKeith Busch 
3*f3813f4bSKeith Busch #include <linux/crc64.h>
4*f3813f4bSKeith Busch #include <linux/module.h>
5*f3813f4bSKeith Busch #include <crypto/internal/hash.h>
6*f3813f4bSKeith Busch #include <asm/unaligned.h>
7*f3813f4bSKeith Busch 
chksum_init(struct shash_desc * desc)8*f3813f4bSKeith Busch static int chksum_init(struct shash_desc *desc)
9*f3813f4bSKeith Busch {
10*f3813f4bSKeith Busch 	u64 *crc = shash_desc_ctx(desc);
11*f3813f4bSKeith Busch 
12*f3813f4bSKeith Busch 	*crc = 0;
13*f3813f4bSKeith Busch 
14*f3813f4bSKeith Busch 	return 0;
15*f3813f4bSKeith Busch }
16*f3813f4bSKeith Busch 
chksum_update(struct shash_desc * desc,const u8 * data,unsigned int length)17*f3813f4bSKeith Busch static int chksum_update(struct shash_desc *desc, const u8 *data,
18*f3813f4bSKeith Busch 			 unsigned int length)
19*f3813f4bSKeith Busch {
20*f3813f4bSKeith Busch 	u64 *crc = shash_desc_ctx(desc);
21*f3813f4bSKeith Busch 
22*f3813f4bSKeith Busch 	*crc = crc64_rocksoft_generic(*crc, data, length);
23*f3813f4bSKeith Busch 
24*f3813f4bSKeith Busch 	return 0;
25*f3813f4bSKeith Busch }
26*f3813f4bSKeith Busch 
chksum_final(struct shash_desc * desc,u8 * out)27*f3813f4bSKeith Busch static int chksum_final(struct shash_desc *desc, u8 *out)
28*f3813f4bSKeith Busch {
29*f3813f4bSKeith Busch 	u64 *crc = shash_desc_ctx(desc);
30*f3813f4bSKeith Busch 
31*f3813f4bSKeith Busch 	put_unaligned_le64(*crc, out);
32*f3813f4bSKeith Busch 	return 0;
33*f3813f4bSKeith Busch }
34*f3813f4bSKeith Busch 
__chksum_finup(u64 crc,const u8 * data,unsigned int len,u8 * out)35*f3813f4bSKeith Busch static int __chksum_finup(u64 crc, const u8 *data, unsigned int len, u8 *out)
36*f3813f4bSKeith Busch {
37*f3813f4bSKeith Busch 	crc = crc64_rocksoft_generic(crc, data, len);
38*f3813f4bSKeith Busch 	put_unaligned_le64(crc, out);
39*f3813f4bSKeith Busch 	return 0;
40*f3813f4bSKeith Busch }
41*f3813f4bSKeith Busch 
chksum_finup(struct shash_desc * desc,const u8 * data,unsigned int len,u8 * out)42*f3813f4bSKeith Busch static int chksum_finup(struct shash_desc *desc, const u8 *data,
43*f3813f4bSKeith Busch 			unsigned int len, u8 *out)
44*f3813f4bSKeith Busch {
45*f3813f4bSKeith Busch 	u64 *crc = shash_desc_ctx(desc);
46*f3813f4bSKeith Busch 
47*f3813f4bSKeith Busch 	return __chksum_finup(*crc, data, len, out);
48*f3813f4bSKeith Busch }
49*f3813f4bSKeith Busch 
chksum_digest(struct shash_desc * desc,const u8 * data,unsigned int length,u8 * out)50*f3813f4bSKeith Busch static int chksum_digest(struct shash_desc *desc, const u8 *data,
51*f3813f4bSKeith Busch 			 unsigned int length, u8 *out)
52*f3813f4bSKeith Busch {
53*f3813f4bSKeith Busch 	return __chksum_finup(0, data, length, out);
54*f3813f4bSKeith Busch }
55*f3813f4bSKeith Busch 
56*f3813f4bSKeith Busch static struct shash_alg alg = {
57*f3813f4bSKeith Busch 	.digestsize	= 	sizeof(u64),
58*f3813f4bSKeith Busch 	.init		=	chksum_init,
59*f3813f4bSKeith Busch 	.update		=	chksum_update,
60*f3813f4bSKeith Busch 	.final		=	chksum_final,
61*f3813f4bSKeith Busch 	.finup		=	chksum_finup,
62*f3813f4bSKeith Busch 	.digest		=	chksum_digest,
63*f3813f4bSKeith Busch 	.descsize	=	sizeof(u64),
64*f3813f4bSKeith Busch 	.base		=	{
65*f3813f4bSKeith Busch 		.cra_name		=	CRC64_ROCKSOFT_STRING,
66*f3813f4bSKeith Busch 		.cra_driver_name	=	"crc64-rocksoft-generic",
67*f3813f4bSKeith Busch 		.cra_priority		=	200,
68*f3813f4bSKeith Busch 		.cra_blocksize		=	1,
69*f3813f4bSKeith Busch 		.cra_module		=	THIS_MODULE,
70*f3813f4bSKeith Busch 	}
71*f3813f4bSKeith Busch };
72*f3813f4bSKeith Busch 
crc64_rocksoft_init(void)73*f3813f4bSKeith Busch static int __init crc64_rocksoft_init(void)
74*f3813f4bSKeith Busch {
75*f3813f4bSKeith Busch 	return crypto_register_shash(&alg);
76*f3813f4bSKeith Busch }
77*f3813f4bSKeith Busch 
crc64_rocksoft_exit(void)78*f3813f4bSKeith Busch static void __exit crc64_rocksoft_exit(void)
79*f3813f4bSKeith Busch {
80*f3813f4bSKeith Busch 	crypto_unregister_shash(&alg);
81*f3813f4bSKeith Busch }
82*f3813f4bSKeith Busch 
83*f3813f4bSKeith Busch module_init(crc64_rocksoft_init);
84*f3813f4bSKeith Busch module_exit(crc64_rocksoft_exit);
85*f3813f4bSKeith Busch 
86*f3813f4bSKeith Busch MODULE_LICENSE("GPL");
87*f3813f4bSKeith Busch MODULE_DESCRIPTION("Rocksoft model CRC64 calculation.");
88*f3813f4bSKeith Busch MODULE_ALIAS_CRYPTO("crc64-rocksoft");
89*f3813f4bSKeith Busch MODULE_ALIAS_CRYPTO("crc64-rocksoft-generic");
90