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