cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

crc32c_generic.c (4196B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Cryptographic API.
      4 *
      5 * CRC32C chksum
      6 *
      7 *@Article{castagnoli-crc,
      8 * author =       { Guy Castagnoli and Stefan Braeuer and Martin Herrman},
      9 * title =        {{Optimization of Cyclic Redundancy-Check Codes with 24
     10 *                 and 32 Parity Bits}},
     11 * journal =      IEEE Transactions on Communication,
     12 * year =         {1993},
     13 * volume =       {41},
     14 * number =       {6},
     15 * pages =        {},
     16 * month =        {June},
     17 *}
     18 * Used by the iSCSI driver, possibly others, and derived from
     19 * the iscsi-crc.c module of the linux-iscsi driver at
     20 * http://linux-iscsi.sourceforge.net.
     21 *
     22 * Following the example of lib/crc32, this function is intended to be
     23 * flexible and useful for all users.  Modules that currently have their
     24 * own crc32c, but hopefully may be able to use this one are:
     25 *  net/sctp (please add all your doco to here if you change to
     26 *            use this one!)
     27 *  <endoflist>
     28 *
     29 * Copyright (c) 2004 Cisco Systems, Inc.
     30 * Copyright (c) 2008 Herbert Xu <herbert@gondor.apana.org.au>
     31 */
     32
     33#include <asm/unaligned.h>
     34#include <crypto/internal/hash.h>
     35#include <linux/init.h>
     36#include <linux/module.h>
     37#include <linux/string.h>
     38#include <linux/kernel.h>
     39#include <linux/crc32.h>
     40
     41#define CHKSUM_BLOCK_SIZE	1
     42#define CHKSUM_DIGEST_SIZE	4
     43
     44struct chksum_ctx {
     45	u32 key;
     46};
     47
     48struct chksum_desc_ctx {
     49	u32 crc;
     50};
     51
     52/*
     53 * Steps through buffer one byte at a time, calculates reflected
     54 * crc using table.
     55 */
     56
     57static int chksum_init(struct shash_desc *desc)
     58{
     59	struct chksum_ctx *mctx = crypto_shash_ctx(desc->tfm);
     60	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
     61
     62	ctx->crc = mctx->key;
     63
     64	return 0;
     65}
     66
     67/*
     68 * Setting the seed allows arbitrary accumulators and flexible XOR policy
     69 * If your algorithm starts with ~0, then XOR with ~0 before you set
     70 * the seed.
     71 */
     72static int chksum_setkey(struct crypto_shash *tfm, const u8 *key,
     73			 unsigned int keylen)
     74{
     75	struct chksum_ctx *mctx = crypto_shash_ctx(tfm);
     76
     77	if (keylen != sizeof(mctx->key))
     78		return -EINVAL;
     79	mctx->key = get_unaligned_le32(key);
     80	return 0;
     81}
     82
     83static int chksum_update(struct shash_desc *desc, const u8 *data,
     84			 unsigned int length)
     85{
     86	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
     87
     88	ctx->crc = __crc32c_le(ctx->crc, data, length);
     89	return 0;
     90}
     91
     92static int chksum_final(struct shash_desc *desc, u8 *out)
     93{
     94	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
     95
     96	put_unaligned_le32(~ctx->crc, out);
     97	return 0;
     98}
     99
    100static int __chksum_finup(u32 *crcp, const u8 *data, unsigned int len, u8 *out)
    101{
    102	put_unaligned_le32(~__crc32c_le(*crcp, data, len), out);
    103	return 0;
    104}
    105
    106static int chksum_finup(struct shash_desc *desc, const u8 *data,
    107			unsigned int len, u8 *out)
    108{
    109	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
    110
    111	return __chksum_finup(&ctx->crc, data, len, out);
    112}
    113
    114static int chksum_digest(struct shash_desc *desc, const u8 *data,
    115			 unsigned int length, u8 *out)
    116{
    117	struct chksum_ctx *mctx = crypto_shash_ctx(desc->tfm);
    118
    119	return __chksum_finup(&mctx->key, data, length, out);
    120}
    121
    122static int crc32c_cra_init(struct crypto_tfm *tfm)
    123{
    124	struct chksum_ctx *mctx = crypto_tfm_ctx(tfm);
    125
    126	mctx->key = ~0;
    127	return 0;
    128}
    129
    130static struct shash_alg alg = {
    131	.digestsize		=	CHKSUM_DIGEST_SIZE,
    132	.setkey			=	chksum_setkey,
    133	.init		=	chksum_init,
    134	.update		=	chksum_update,
    135	.final		=	chksum_final,
    136	.finup		=	chksum_finup,
    137	.digest		=	chksum_digest,
    138	.descsize		=	sizeof(struct chksum_desc_ctx),
    139	.base			=	{
    140		.cra_name		=	"crc32c",
    141		.cra_driver_name	=	"crc32c-generic",
    142		.cra_priority		=	100,
    143		.cra_flags		=	CRYPTO_ALG_OPTIONAL_KEY,
    144		.cra_blocksize		=	CHKSUM_BLOCK_SIZE,
    145		.cra_ctxsize		=	sizeof(struct chksum_ctx),
    146		.cra_module		=	THIS_MODULE,
    147		.cra_init		=	crc32c_cra_init,
    148	}
    149};
    150
    151static int __init crc32c_mod_init(void)
    152{
    153	return crypto_register_shash(&alg);
    154}
    155
    156static void __exit crc32c_mod_fini(void)
    157{
    158	crypto_unregister_shash(&alg);
    159}
    160
    161subsys_initcall(crc32c_mod_init);
    162module_exit(crc32c_mod_fini);
    163
    164MODULE_AUTHOR("Clay Haapala <chaapala@cisco.com>");
    165MODULE_DESCRIPTION("CRC32c (Castagnoli) calculations wrapper for lib/crc32c");
    166MODULE_LICENSE("GPL");
    167MODULE_ALIAS_CRYPTO("crc32c");
    168MODULE_ALIAS_CRYPTO("crc32c-generic");