Back to home page

LXR

 
 

    


0001 /* GPL HEADER START
0002  *
0003  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004  *
0005  * This program is free software; you can redistribute it and/or modify
0006  * it under the terms of the GNU General Public License version 2 only,
0007  * as published by the Free Software Foundation.
0008  *
0009  * This program is distributed in the hope that it will be useful, but
0010  * WITHOUT ANY WARRANTY; without even the implied warranty of
0011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012  * General Public License version 2 for more details (a copy is included
0013  * in the LICENSE file that accompanied this code).
0014  *
0015  * You should have received a copy of the GNU General Public License
0016  * version 2 along with this program; If not, see http://www.gnu.org/licenses
0017  *
0018  * Please  visit http://www.xyratex.com/contact if you need additional
0019  * information or have any questions.
0020  *
0021  * GPL HEADER END
0022  */
0023 
0024 /*
0025  * Copyright 2012 Xyratex Technology Limited
0026  */
0027 
0028 /*
0029  * This is crypto api shash wrappers to crc32_le.
0030  */
0031 
0032 #include <linux/crc32.h>
0033 #include <crypto/internal/hash.h>
0034 #include <linux/init.h>
0035 #include <linux/module.h>
0036 #include <linux/string.h>
0037 #include <linux/kernel.h>
0038 
0039 #define CHKSUM_BLOCK_SIZE   1
0040 #define CHKSUM_DIGEST_SIZE  4
0041 
0042 static u32 __crc32_le(u32 crc, unsigned char const *p, size_t len)
0043 {
0044     return crc32_le(crc, p, len);
0045 }
0046 
0047 /** No default init with ~0 */
0048 static int crc32_cra_init(struct crypto_tfm *tfm)
0049 {
0050     u32 *key = crypto_tfm_ctx(tfm);
0051 
0052     *key = 0;
0053 
0054     return 0;
0055 }
0056 
0057 
0058 /*
0059  * Setting the seed allows arbitrary accumulators and flexible XOR policy
0060  * If your algorithm starts with ~0, then XOR with ~0 before you set
0061  * the seed.
0062  */
0063 static int crc32_setkey(struct crypto_shash *hash, const u8 *key,
0064             unsigned int keylen)
0065 {
0066     u32 *mctx = crypto_shash_ctx(hash);
0067 
0068     if (keylen != sizeof(u32)) {
0069         crypto_shash_set_flags(hash, CRYPTO_TFM_RES_BAD_KEY_LEN);
0070         return -EINVAL;
0071     }
0072     *mctx = le32_to_cpup((__le32 *)key);
0073     return 0;
0074 }
0075 
0076 static int crc32_init(struct shash_desc *desc)
0077 {
0078     u32 *mctx = crypto_shash_ctx(desc->tfm);
0079     u32 *crcp = shash_desc_ctx(desc);
0080 
0081     *crcp = *mctx;
0082 
0083     return 0;
0084 }
0085 
0086 static int crc32_update(struct shash_desc *desc, const u8 *data,
0087             unsigned int len)
0088 {
0089     u32 *crcp = shash_desc_ctx(desc);
0090 
0091     *crcp = __crc32_le(*crcp, data, len);
0092     return 0;
0093 }
0094 
0095 /* No final XOR 0xFFFFFFFF, like crc32_le */
0096 static int __crc32_finup(u32 *crcp, const u8 *data, unsigned int len,
0097              u8 *out)
0098 {
0099     *(__le32 *)out = cpu_to_le32(__crc32_le(*crcp, data, len));
0100     return 0;
0101 }
0102 
0103 static int crc32_finup(struct shash_desc *desc, const u8 *data,
0104                unsigned int len, u8 *out)
0105 {
0106     return __crc32_finup(shash_desc_ctx(desc), data, len, out);
0107 }
0108 
0109 static int crc32_final(struct shash_desc *desc, u8 *out)
0110 {
0111     u32 *crcp = shash_desc_ctx(desc);
0112 
0113     *(__le32 *)out = cpu_to_le32p(crcp);
0114     return 0;
0115 }
0116 
0117 static int crc32_digest(struct shash_desc *desc, const u8 *data,
0118             unsigned int len, u8 *out)
0119 {
0120     return __crc32_finup(crypto_shash_ctx(desc->tfm), data, len,
0121                  out);
0122 }
0123 static struct shash_alg alg = {
0124     .setkey     = crc32_setkey,
0125     .init       = crc32_init,
0126     .update     = crc32_update,
0127     .final      = crc32_final,
0128     .finup      = crc32_finup,
0129     .digest     = crc32_digest,
0130     .descsize   = sizeof(u32),
0131     .digestsize = CHKSUM_DIGEST_SIZE,
0132     .base       = {
0133         .cra_name       = "crc32",
0134         .cra_driver_name    = "crc32-generic",
0135         .cra_priority       = 100,
0136         .cra_blocksize      = CHKSUM_BLOCK_SIZE,
0137         .cra_ctxsize        = sizeof(u32),
0138         .cra_module     = THIS_MODULE,
0139         .cra_init       = crc32_cra_init,
0140     }
0141 };
0142 
0143 static int __init crc32_mod_init(void)
0144 {
0145     return crypto_register_shash(&alg);
0146 }
0147 
0148 static void __exit crc32_mod_fini(void)
0149 {
0150     crypto_unregister_shash(&alg);
0151 }
0152 
0153 module_init(crc32_mod_init);
0154 module_exit(crc32_mod_fini);
0155 
0156 MODULE_AUTHOR("Alexander Boyko <alexander_boyko@xyratex.com>");
0157 MODULE_DESCRIPTION("CRC32 calculations wrapper for lib/crc32");
0158 MODULE_LICENSE("GPL");
0159 MODULE_ALIAS_CRYPTO("crc32");
0160 MODULE_ALIAS_CRYPTO("crc32-generic");