18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * CRC32C 48c2ecf20Sopenharmony_ci *@Article{castagnoli-crc, 58c2ecf20Sopenharmony_ci * author = { Guy Castagnoli and Stefan Braeuer and Martin Herrman}, 68c2ecf20Sopenharmony_ci * title = {{Optimization of Cyclic Redundancy-Check Codes with 24 78c2ecf20Sopenharmony_ci * and 32 Parity Bits}}, 88c2ecf20Sopenharmony_ci * journal = IEEE Transactions on Communication, 98c2ecf20Sopenharmony_ci * year = {1993}, 108c2ecf20Sopenharmony_ci * volume = {41}, 118c2ecf20Sopenharmony_ci * number = {6}, 128c2ecf20Sopenharmony_ci * pages = {}, 138c2ecf20Sopenharmony_ci * month = {June}, 148c2ecf20Sopenharmony_ci *} 158c2ecf20Sopenharmony_ci * Used by the iSCSI driver, possibly others, and derived from 168c2ecf20Sopenharmony_ci * the iscsi-crc.c module of the linux-iscsi driver at 178c2ecf20Sopenharmony_ci * http://linux-iscsi.sourceforge.net. 188c2ecf20Sopenharmony_ci * 198c2ecf20Sopenharmony_ci * Following the example of lib/crc32, this function is intended to be 208c2ecf20Sopenharmony_ci * flexible and useful for all users. Modules that currently have their 218c2ecf20Sopenharmony_ci * own crc32c, but hopefully may be able to use this one are: 228c2ecf20Sopenharmony_ci * net/sctp (please add all your doco to here if you change to 238c2ecf20Sopenharmony_ci * use this one!) 248c2ecf20Sopenharmony_ci * <endoflist> 258c2ecf20Sopenharmony_ci * 268c2ecf20Sopenharmony_ci * Copyright (c) 2004 Cisco Systems, Inc. 278c2ecf20Sopenharmony_ci */ 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci#include <crypto/hash.h> 308c2ecf20Sopenharmony_ci#include <linux/err.h> 318c2ecf20Sopenharmony_ci#include <linux/init.h> 328c2ecf20Sopenharmony_ci#include <linux/kernel.h> 338c2ecf20Sopenharmony_ci#include <linux/module.h> 348c2ecf20Sopenharmony_ci#include <linux/crc32c.h> 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_cistatic struct crypto_shash *tfm; 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ciu32 crc32c(u32 crc, const void *address, unsigned int length) 398c2ecf20Sopenharmony_ci{ 408c2ecf20Sopenharmony_ci SHASH_DESC_ON_STACK(shash, tfm); 418c2ecf20Sopenharmony_ci u32 ret, *ctx = (u32 *)shash_desc_ctx(shash); 428c2ecf20Sopenharmony_ci int err; 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci shash->tfm = tfm; 458c2ecf20Sopenharmony_ci *ctx = crc; 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci err = crypto_shash_update(shash, address, length); 488c2ecf20Sopenharmony_ci BUG_ON(err); 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci ret = *ctx; 518c2ecf20Sopenharmony_ci barrier_data(ctx); 528c2ecf20Sopenharmony_ci return ret; 538c2ecf20Sopenharmony_ci} 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ciEXPORT_SYMBOL(crc32c); 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_cistatic int __init libcrc32c_mod_init(void) 588c2ecf20Sopenharmony_ci{ 598c2ecf20Sopenharmony_ci tfm = crypto_alloc_shash("crc32c", 0, 0); 608c2ecf20Sopenharmony_ci return PTR_ERR_OR_ZERO(tfm); 618c2ecf20Sopenharmony_ci} 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_cistatic void __exit libcrc32c_mod_fini(void) 648c2ecf20Sopenharmony_ci{ 658c2ecf20Sopenharmony_ci crypto_free_shash(tfm); 668c2ecf20Sopenharmony_ci} 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ciconst char *crc32c_impl(void) 698c2ecf20Sopenharmony_ci{ 708c2ecf20Sopenharmony_ci return crypto_shash_driver_name(tfm); 718c2ecf20Sopenharmony_ci} 728c2ecf20Sopenharmony_ciEXPORT_SYMBOL(crc32c_impl); 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_cimodule_init(libcrc32c_mod_init); 758c2ecf20Sopenharmony_cimodule_exit(libcrc32c_mod_fini); 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ciMODULE_AUTHOR("Clay Haapala <chaapala@cisco.com>"); 788c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("CRC32c (Castagnoli) calculations"); 798c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 808c2ecf20Sopenharmony_ciMODULE_SOFTDEP("pre: crc32c"); 81