Commit f3813f4b authored by Keith Busch's avatar Keith Busch Committed by Jens Axboe
Browse files

crypto: add rocksoft 64b crc guard tag framework



Hardware specific features may be able to calculate a crc64, so provide
a framework for drivers to register their implementation. If nothing is
registered, fallback to the generic table lookup implementation. The
implementation is modeled after the crct10dif equivalent.

Signed-off-by: default avatarKeith Busch <kbusch@kernel.org>
Link: https://lore.kernel.org/r/20220303201312.3255347-7-kbusch@kernel.org


Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent cbc0a40e
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -735,6 +735,11 @@ config CRYPTO_CRCT10DIF_VPMSUM
	  multiply-sum (vpmsum) instructions, introduced in POWER8. Enable on
	  POWER8 and newer processors for improved performance.

config CRYPTO_CRC64_ROCKSOFT
	tristate "Rocksoft Model CRC64 algorithm"
	depends on CRC64
	select CRYPTO_HASH

config CRYPTO_VPMSUM_TESTER
	tristate "Powerpc64 vpmsum hardware acceleration tester"
	depends on CRYPTO_CRCT10DIF_VPMSUM && CRYPTO_CRC32C_VPMSUM
+1 −0
Original line number Diff line number Diff line
@@ -152,6 +152,7 @@ obj-$(CONFIG_CRYPTO_MICHAEL_MIC) += michael_mic.o
obj-$(CONFIG_CRYPTO_CRC32C) += crc32c_generic.o
obj-$(CONFIG_CRYPTO_CRC32) += crc32_generic.o
obj-$(CONFIG_CRYPTO_CRCT10DIF) += crct10dif_common.o crct10dif_generic.o
obj-$(CONFIG_CRYPTO_CRC64_ROCKSOFT) += crc64_rocksoft_generic.o
obj-$(CONFIG_CRYPTO_AUTHENC) += authenc.o authencesn.o
obj-$(CONFIG_CRYPTO_LZO) += lzo.o lzo-rle.o
obj-$(CONFIG_CRYPTO_LZ4) += lz4.o
+89 −0
Original line number Diff line number Diff line
// 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");
+7 −0
Original line number Diff line number Diff line
@@ -4526,6 +4526,13 @@ static const struct alg_test_desc alg_test_descs[] = {
		.suite = {
			.hash = __VECS(crc32c_tv_template)
		}
	}, {
		.alg = "crc64-rocksoft",
		.test = alg_test_hash,
		.fips_allowed = 1,
		.suite = {
			.hash = __VECS(crc64_rocksoft_tv_template)
		}
	}, {
		.alg = "crct10dif",
		.test = alg_test_hash,
+15 −0
Original line number Diff line number Diff line
@@ -3679,6 +3679,21 @@ static const struct hash_testvec rmd160_tv_template[] = {
	}
};
static const u8 zeroes[4096] = { [0 ... 4095] = 0 };
static const u8 ones[4096] = { [0 ... 4095] = 0xff };
static const struct hash_testvec crc64_rocksoft_tv_template[] = {
	{
		.plaintext	= zeroes,
		.psize		= 4096,
		.digest		= (u8 *)(u64[]){ 0x6482d367eb22b64eull },
	}, {
		.plaintext	= ones,
		.psize		= 4096,
		.digest		= (u8 *)(u64[]){ 0xc0ddba7302eca3acull },
	}
};
static const struct hash_testvec crct10dif_tv_template[] = {
	{
		.plaintext	= "abc",
Loading