Back to home page

LXR

 
 

    


0001 /*
0002  * T10 Data Integrity Field CRC16 calculation
0003  *
0004  * Copyright (c) 2007 Oracle Corporation.  All rights reserved.
0005  * Written by Martin K. Petersen <martin.petersen@oracle.com>
0006  *
0007  * This source code is licensed under the GNU General Public License,
0008  * Version 2. See the file COPYING for more details.
0009  */
0010 
0011 #include <linux/types.h>
0012 #include <linux/module.h>
0013 #include <linux/crc-t10dif.h>
0014 #include <linux/err.h>
0015 #include <linux/init.h>
0016 #include <crypto/hash.h>
0017 #include <linux/static_key.h>
0018 
0019 static struct crypto_shash *crct10dif_tfm;
0020 static struct static_key crct10dif_fallback __read_mostly;
0021 
0022 __u16 crc_t10dif_update(__u16 crc, const unsigned char *buffer, size_t len)
0023 {
0024     struct {
0025         struct shash_desc shash;
0026         char ctx[2];
0027     } desc;
0028     int err;
0029 
0030     if (static_key_false(&crct10dif_fallback))
0031         return crc_t10dif_generic(crc, buffer, len);
0032 
0033     desc.shash.tfm = crct10dif_tfm;
0034     desc.shash.flags = 0;
0035     *(__u16 *)desc.ctx = crc;
0036 
0037     err = crypto_shash_update(&desc.shash, buffer, len);
0038     BUG_ON(err);
0039 
0040     return *(__u16 *)desc.ctx;
0041 }
0042 EXPORT_SYMBOL(crc_t10dif_update);
0043 
0044 __u16 crc_t10dif(const unsigned char *buffer, size_t len)
0045 {
0046     return crc_t10dif_update(0, buffer, len);
0047 }
0048 EXPORT_SYMBOL(crc_t10dif);
0049 
0050 static int __init crc_t10dif_mod_init(void)
0051 {
0052     crct10dif_tfm = crypto_alloc_shash("crct10dif", 0, 0);
0053     if (IS_ERR(crct10dif_tfm)) {
0054         static_key_slow_inc(&crct10dif_fallback);
0055         crct10dif_tfm = NULL;
0056     }
0057     return 0;
0058 }
0059 
0060 static void __exit crc_t10dif_mod_fini(void)
0061 {
0062     crypto_free_shash(crct10dif_tfm);
0063 }
0064 
0065 module_init(crc_t10dif_mod_init);
0066 module_exit(crc_t10dif_mod_fini);
0067 
0068 MODULE_DESCRIPTION("T10 DIF CRC calculation");
0069 MODULE_LICENSE("GPL");
0070 MODULE_SOFTDEP("pre: crct10dif");