summaryrefslogtreecommitdiffstats
path: root/crypto/crc64_rocksoft_generic.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2022-03-26 12:01:35 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2022-03-26 12:01:35 -0700
commit3f7282139fe1594be464b90141d56738e7a0ea8a (patch)
tree2a6dfc4449ceeee6b5509c3fcc58c33865c89af6 /crypto/crc64_rocksoft_generic.c
parent752d422e74c41084c3c9c9a159cb8d2795fa0c22 (diff)
parent1e21270685ae4c14361dd501da62cdc4be867d4e (diff)
downloadcachepc-linux-3f7282139fe1594be464b90141d56738e7a0ea8a.tar.gz
cachepc-linux-3f7282139fe1594be464b90141d56738e7a0ea8a.zip
Merge tag 'for-5.18/64bit-pi-2022-03-25' of git://git.kernel.dk/linux-block
Pull block layer 64-bit data integrity support from Jens Axboe: "This adds support for 64-bit data integrity in the block layer and in NVMe" * tag 'for-5.18/64bit-pi-2022-03-25' of git://git.kernel.dk/linux-block: crypto: fix crc64 testmgr digest byte order nvme: add support for enhanced metadata block: add pi for extended integrity crypto: add rocksoft 64b crc guard tag framework lib: add rocksoft model crc64 linux/kernel: introduce lower_48_bits function asm-generic: introduce be48 unaligned accessors nvme: allow integrity on extended metadata formats block: support pi with extended metadata
Diffstat (limited to 'crypto/crc64_rocksoft_generic.c')
-rw-r--r--crypto/crc64_rocksoft_generic.c89
1 files changed, 89 insertions, 0 deletions
diff --git a/crypto/crc64_rocksoft_generic.c b/crypto/crc64_rocksoft_generic.c
new file mode 100644
index 000000000000..9e812bb26dba
--- /dev/null
+++ b/crypto/crc64_rocksoft_generic.c
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/crc64.h>
+#include <linux/module.h>
+#include <crypto/internal/hash.h>
+#include <asm/unaligned.h>
+
+static int chksum_init(struct shash_desc *desc)
+{
+ u64 *crc = shash_desc_ctx(desc);
+
+ *crc = 0;
+
+ return 0;
+}
+
+static int chksum_update(struct shash_desc *desc, const u8 *data,
+ unsigned int length)
+{
+ u64 *crc = shash_desc_ctx(desc);
+
+ *crc = crc64_rocksoft_generic(*crc, data, length);
+
+ return 0;
+}
+
+static int chksum_final(struct shash_desc *desc, u8 *out)
+{
+ u64 *crc = shash_desc_ctx(desc);
+
+ put_unaligned_le64(*crc, out);
+ return 0;
+}
+
+static int __chksum_finup(u64 crc, const u8 *data, unsigned int len, u8 *out)
+{
+ crc = crc64_rocksoft_generic(crc, data, len);
+ put_unaligned_le64(crc, out);
+ return 0;
+}
+
+static int chksum_finup(struct shash_desc *desc, const u8 *data,
+ unsigned int len, u8 *out)
+{
+ u64 *crc = shash_desc_ctx(desc);
+
+ return __chksum_finup(*crc, data, len, out);
+}
+
+static int chksum_digest(struct shash_desc *desc, const u8 *data,
+ unsigned int length, u8 *out)
+{
+ return __chksum_finup(0, data, length, out);
+}
+
+static struct shash_alg alg = {
+ .digestsize = sizeof(u64),
+ .init = chksum_init,
+ .update = chksum_update,
+ .final = chksum_final,
+ .finup = chksum_finup,
+ .digest = chksum_digest,
+ .descsize = sizeof(u64),
+ .base = {
+ .cra_name = CRC64_ROCKSOFT_STRING,
+ .cra_driver_name = "crc64-rocksoft-generic",
+ .cra_priority = 200,
+ .cra_blocksize = 1,
+ .cra_module = THIS_MODULE,
+ }
+};
+
+static int __init crc64_rocksoft_init(void)
+{
+ return crypto_register_shash(&alg);
+}
+
+static void __exit crc64_rocksoft_exit(void)
+{
+ crypto_unregister_shash(&alg);
+}
+
+module_init(crc64_rocksoft_init);
+module_exit(crc64_rocksoft_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Rocksoft model CRC64 calculation.");
+MODULE_ALIAS_CRYPTO("crc64-rocksoft");
+MODULE_ALIAS_CRYPTO("crc64-rocksoft-generic");