root/crypto/crc32c_generic.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. chksum_init
  2. chksum_setkey
  3. chksum_update
  4. chksum_final
  5. __chksum_finup
  6. chksum_finup
  7. chksum_digest
  8. crc32c_cra_init
  9. crc32c_mod_init
  10. crc32c_mod_fini

   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 the
  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 
  44 struct chksum_ctx {
  45         u32 key;
  46 };
  47 
  48 struct chksum_desc_ctx {
  49         u32 crc;
  50 };
  51 
  52 /*
  53  * Steps through buffer one byte at at time, calculates reflected
  54  * crc using table.
  55  */
  56 
  57 static 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  */
  72 static 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                 crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
  79                 return -EINVAL;
  80         }
  81         mctx->key = get_unaligned_le32(key);
  82         return 0;
  83 }
  84 
  85 static int chksum_update(struct shash_desc *desc, const u8 *data,
  86                          unsigned int length)
  87 {
  88         struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
  89 
  90         ctx->crc = __crc32c_le(ctx->crc, data, length);
  91         return 0;
  92 }
  93 
  94 static int chksum_final(struct shash_desc *desc, u8 *out)
  95 {
  96         struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
  97 
  98         put_unaligned_le32(~ctx->crc, out);
  99         return 0;
 100 }
 101 
 102 static int __chksum_finup(u32 *crcp, const u8 *data, unsigned int len, u8 *out)
 103 {
 104         put_unaligned_le32(~__crc32c_le(*crcp, data, len), out);
 105         return 0;
 106 }
 107 
 108 static int chksum_finup(struct shash_desc *desc, const u8 *data,
 109                         unsigned int len, u8 *out)
 110 {
 111         struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
 112 
 113         return __chksum_finup(&ctx->crc, data, len, out);
 114 }
 115 
 116 static int chksum_digest(struct shash_desc *desc, const u8 *data,
 117                          unsigned int length, u8 *out)
 118 {
 119         struct chksum_ctx *mctx = crypto_shash_ctx(desc->tfm);
 120 
 121         return __chksum_finup(&mctx->key, data, length, out);
 122 }
 123 
 124 static int crc32c_cra_init(struct crypto_tfm *tfm)
 125 {
 126         struct chksum_ctx *mctx = crypto_tfm_ctx(tfm);
 127 
 128         mctx->key = ~0;
 129         return 0;
 130 }
 131 
 132 static struct shash_alg alg = {
 133         .digestsize             =       CHKSUM_DIGEST_SIZE,
 134         .setkey                 =       chksum_setkey,
 135         .init           =       chksum_init,
 136         .update         =       chksum_update,
 137         .final          =       chksum_final,
 138         .finup          =       chksum_finup,
 139         .digest         =       chksum_digest,
 140         .descsize               =       sizeof(struct chksum_desc_ctx),
 141         .base                   =       {
 142                 .cra_name               =       "crc32c",
 143                 .cra_driver_name        =       "crc32c-generic",
 144                 .cra_priority           =       100,
 145                 .cra_flags              =       CRYPTO_ALG_OPTIONAL_KEY,
 146                 .cra_blocksize          =       CHKSUM_BLOCK_SIZE,
 147                 .cra_ctxsize            =       sizeof(struct chksum_ctx),
 148                 .cra_module             =       THIS_MODULE,
 149                 .cra_init               =       crc32c_cra_init,
 150         }
 151 };
 152 
 153 static int __init crc32c_mod_init(void)
 154 {
 155         return crypto_register_shash(&alg);
 156 }
 157 
 158 static void __exit crc32c_mod_fini(void)
 159 {
 160         crypto_unregister_shash(&alg);
 161 }
 162 
 163 subsys_initcall(crc32c_mod_init);
 164 module_exit(crc32c_mod_fini);
 165 
 166 MODULE_AUTHOR("Clay Haapala <chaapala@cisco.com>");
 167 MODULE_DESCRIPTION("CRC32c (Castagnoli) calculations wrapper for lib/crc32c");
 168 MODULE_LICENSE("GPL");
 169 MODULE_ALIAS_CRYPTO("crc32c");
 170 MODULE_ALIAS_CRYPTO("crc32c-generic");

/* [<][>][^][v][top][bottom][index][help] */