libcrc32c: Move implementation to crypto crc32c
authorHerbert Xu <herbert@gondor.apana.org.au>
Fri, 7 Nov 2008 07:11:47 +0000 (15:11 +0800)
committerHerbert Xu <herbert@gondor.apana.org.au>
Thu, 25 Dec 2008 00:01:40 +0000 (11:01 +1100)
This patch swaps the role of libcrc32c and crc32c.  Previously
the implementation was in libcrc32c and crc32c was a wrapper.
Now the code is in crc32c and libcrc32c just calls the crypto
layer.

The reason for the change is to tap into the algorithm selection
capability of the crypto API so that optimised implementations
such as the one utilising Intel's CRC32C instruction can be
used where available.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
crypto/Kconfig
crypto/crc32c.c
include/linux/crc32c.h
lib/Kconfig
lib/libcrc32c.c

index dc20a34ba5efaf9922cf225f1ec18a962b5f1024..aede80246df2165929f102405fea56e885316442 100644 (file)
@@ -256,12 +256,10 @@ comment "Digest"
 config CRYPTO_CRC32C
        tristate "CRC32c CRC algorithm"
        select CRYPTO_HASH
-       select LIBCRC32C
        help
          Castagnoli, et al Cyclic Redundancy-Check Algorithm.  Used
          by iSCSI for header and data digests and by others.
-         See Castagnoli93.  This implementation uses lib/libcrc32c.
-         Module will be crc32c.
+         See Castagnoli93.  Module will be crc32c.
 
 config CRYPTO_CRC32C_INTEL
        tristate "CRC32c INTEL hardware acceleration"
index b21b93f2bb903da8604a2eebf8fc35732b6093eb..973bc2cfab2ec00b8571894bc7ceb35541670cad 100644 (file)
@@ -3,8 +3,29 @@
  *
  * CRC32C chksum
  *
- * This module file is a wrapper to invoke the lib/crc32c routines.
+ *@Article{castagnoli-crc,
+ * author =       { Guy Castagnoli and Stefan Braeuer and Martin Herrman},
+ * title =        {{Optimization of Cyclic Redundancy-Check Codes with 24
+ *                 and 32 Parity Bits}},
+ * journal =      IEEE Transactions on Communication,
+ * year =         {1993},
+ * volume =       {41},
+ * number =       {6},
+ * pages =        {},
+ * month =        {June},
+ *}
+ * Used by the iSCSI driver, possibly others, and derived from the
+ * the iscsi-crc.c module of the linux-iscsi driver at
+ * http://linux-iscsi.sourceforge.net.
  *
+ * Following the example of lib/crc32, this function is intended to be
+ * flexible and useful for all users.  Modules that currently have their
+ * own crc32c, but hopefully may be able to use this one are:
+ *  net/sctp (please add all your doco to here if you change to
+ *            use this one!)
+ *  <endoflist>
+ *
+ * Copyright (c) 2004 Cisco Systems, Inc.
  * Copyright (c) 2008 Herbert Xu <herbert@gondor.apana.org.au>
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -18,7 +39,6 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/string.h>
-#include <linux/crc32c.h>
 #include <linux/kernel.h>
 
 #define CHKSUM_BLOCK_SIZE      1
@@ -32,6 +52,95 @@ struct chksum_desc_ctx {
        u32 crc;
 };
 
+/*
+ * This is the CRC-32C table
+ * Generated with:
+ * width = 32 bits
+ * poly = 0x1EDC6F41
+ * reflect input bytes = true
+ * reflect output bytes = true
+ */
+
+static const u32 crc32c_table[256] = {
+       0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L,
+       0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL,
+       0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL,
+       0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L,
+       0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL,
+       0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L,
+       0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L,
+       0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL,
+       0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL,
+       0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L,
+       0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L,
+       0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL,
+       0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L,
+       0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL,
+       0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL,
+       0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L,
+       0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L,
+       0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L,
+       0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L,
+       0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L,
+       0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L,
+       0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L,
+       0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L,
+       0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L,
+       0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L,
+       0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L,
+       0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L,
+       0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L,
+       0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L,
+       0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L,
+       0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L,
+       0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L,
+       0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL,
+       0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L,
+       0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L,
+       0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL,
+       0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L,
+       0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL,
+       0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL,
+       0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L,
+       0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L,
+       0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL,
+       0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL,
+       0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L,
+       0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL,
+       0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L,
+       0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L,
+       0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL,
+       0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L,
+       0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL,
+       0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL,
+       0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L,
+       0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL,
+       0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L,
+       0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L,
+       0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL,
+       0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL,
+       0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L,
+       0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L,
+       0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL,
+       0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L,
+       0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL,
+       0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL,
+       0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L
+};
+
+/*
+ * Steps through buffer one byte at at time, calculates reflected
+ * crc using table.
+ */
+
+static u32 crc32c(u32 crc, const u8 *data, unsigned int length)
+{
+       while (length--)
+               crc = crc32c_table[(crc ^ *data++) & 0xFFL] ^ (crc >> 8);
+
+       return crc;
+}
+
 /*
  * Steps through buffer one byte at at time, calculates reflected 
  * crc using table.
index 508f512e5a2fcebbaf1f243e7a4fd42a7ace96db..66fa8ff795ec5431fae513c0886ae56c47a6ec6e 100644 (file)
@@ -3,9 +3,6 @@
 
 #include <linux/types.h>
 
-extern u32 crc32c_le(u32 crc, unsigned char const *address, size_t length);
-extern u32 crc32c_be(u32 crc, unsigned char const *address, size_t length);
-
-#define crc32c(seed, data, length)  crc32c_le(seed, (unsigned char const *)data, length)
+extern u32 crc32c(u32 crc, const void *address, unsigned int length);
 
 #endif /* _LINUX_CRC32C_H */
index 85cf7ea978aafe6606e6e44cc634a82e6cf29477..ce303f13ed927c199af407db02beae2e12e7c5e0 100644 (file)
@@ -64,6 +64,7 @@ config CRC7
 
 config LIBCRC32C
        tristate "CRC32c (Castagnoli, et al) Cyclic Redundancy-Check"
+       select CRYPTO_CRC32C
        help
          This option is provided for the case where no in-kernel-tree
          modules require CRC32c functions, but a module built outside the
index b5c3287d8ea47567220cbafd2211dd12b5239356..38b17ab52ff9e0186aeb8386bf68b2f67845687a 100644 (file)
  * any later version.
  *
  */
-#include <linux/crc32c.h>
-#include <linux/compiler.h>
-#include <linux/module.h>
-
-MODULE_AUTHOR("Clay Haapala <chaapala@cisco.com>");
-MODULE_DESCRIPTION("CRC32c (Castagnoli) calculations");
-MODULE_LICENSE("GPL");
-
-#define CRC32C_POLY_BE 0x1EDC6F41
-#define CRC32C_POLY_LE 0x82F63B78
 
-#ifndef CRC_LE_BITS 
-# define CRC_LE_BITS 8
-#endif
-
-
-/*
- * Haven't generated a big-endian table yet, but the bit-wise version
- * should at least work.
- */
-#if defined CRC_BE_BITS && CRC_BE_BITS != 1
-#undef CRC_BE_BITS
-#endif
-#ifndef CRC_BE_BITS
-# define CRC_BE_BITS 1
-#endif
+#include <crypto/hash.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 
-EXPORT_SYMBOL(crc32c_le);
+static struct crypto_shash *tfm;
 
-#if CRC_LE_BITS == 1
-/*
- * Compute things bit-wise, as done in crc32.c.  We could share the tight 
- * loop below with crc32 and vary the POLY if we don't find value in terms
- * of space and maintainability in keeping the two modules separate.
- */
-u32 __pure
-crc32c_le(u32 crc, unsigned char const *p, size_t len)
+u32 crc32c(u32 crc, const void *address, unsigned int length)
 {
-       int i;
-       while (len--) {
-               crc ^= *p++;
-               for (i = 0; i < 8; i++)
-                       crc = (crc >> 1) ^ ((crc & 1) ? CRC32C_POLY_LE : 0);
-       }
-       return crc;
-}
-#else
+       struct {
+               struct shash_desc shash;
+               char ctx[crypto_shash_descsize(tfm)];
+       } desc;
+       int err;
 
-/*
- * This is the CRC-32C table
- * Generated with:
- * width = 32 bits
- * poly = 0x1EDC6F41
- * reflect input bytes = true
- * reflect output bytes = true
- */
+       desc.shash.tfm = tfm;
+       desc.shash.flags = 0;
+       *(u32 *)desc.ctx = crc;
 
-static const u32 crc32c_table[256] = {
-       0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L,
-       0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL,
-       0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL,
-       0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L,
-       0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL,
-       0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L,
-       0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L,
-       0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL,
-       0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL,
-       0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L,
-       0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L,
-       0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL,
-       0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L,
-       0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL,
-       0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL,
-       0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L,
-       0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L,
-       0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L,
-       0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L,
-       0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L,
-       0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L,
-       0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L,
-       0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L,
-       0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L,
-       0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L,
-       0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L,
-       0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L,
-       0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L,
-       0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L,
-       0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L,
-       0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L,
-       0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L,
-       0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL,
-       0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L,
-       0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L,
-       0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL,
-       0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L,
-       0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL,
-       0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL,
-       0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L,
-       0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L,
-       0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL,
-       0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL,
-       0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L,
-       0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL,
-       0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L,
-       0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L,
-       0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL,
-       0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L,
-       0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL,
-       0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL,
-       0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L,
-       0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL,
-       0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L,
-       0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L,
-       0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL,
-       0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL,
-       0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L,
-       0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L,
-       0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL,
-       0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L,
-       0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL,
-       0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL,
-       0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L
-};
+       err = crypto_shash_update(&desc.shash, address, length);
+       BUG_ON(err);
 
-/*
- * Steps through buffer one byte at at time, calculates reflected 
- * crc using table.
- */
+       return *(u32 *)desc.ctx;
+}
 
-u32 __pure
-crc32c_le(u32 crc, unsigned char const *data, size_t length)
+static int __init libcrc32c_mod_init(void)
 {
-       while (length--)
-               crc =
-                   crc32c_table[(crc ^ *data++) & 0xFFL] ^ (crc >> 8);
+       tfm = crypto_alloc_shash("crc32c", 0, 0);
+       if (IS_ERR(tfm))
+               return PTR_ERR(tfm);
 
-       return crc;
+       return 0;
 }
 
-#endif /* CRC_LE_BITS == 8 */
-
-EXPORT_SYMBOL(crc32c_be);
-
-#if CRC_BE_BITS == 1
-u32 __pure
-crc32c_be(u32 crc, unsigned char const *p, size_t len)
+static void __exit libcrc32c_mod_fini(void)
 {
-       int i;
-       while (len--) {
-               crc ^= *p++ << 24;
-               for (i = 0; i < 8; i++)
-                       crc =
-                           (crc << 1) ^ ((crc & 0x80000000) ? CRC32C_POLY_BE :
-                                         0);
-       }
-       return crc;
+       crypto_free_shash(tfm);
 }
-#endif
 
-/*
- * Unit test
- *
- * A small unit test suite is implemented as part of the crypto suite.
- * Select CRYPTO_CRC32C and use the tcrypt module to run the tests.
- */
+module_init(libcrc32c_mod_init);
+module_exit(libcrc32c_mod_fini);
+
+MODULE_AUTHOR("Clay Haapala <chaapala@cisco.com>");
+MODULE_DESCRIPTION("CRC32c (Castagnoli) calculations");
+MODULE_LICENSE("GPL");