0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/crc-t10dif.h>
0009 #include <linux/init.h>
0010 #include <linux/kernel.h>
0011 #include <linux/module.h>
0012 #include <linux/string.h>
0013
0014 #include <crypto/internal/hash.h>
0015 #include <crypto/internal/simd.h>
0016
0017 #include <asm/neon.h>
0018 #include <asm/simd.h>
0019
0020 #define CRC_T10DIF_PMULL_CHUNK_SIZE 16U
0021
0022 asmlinkage u16 crc_t10dif_pmull(u16 init_crc, const u8 *buf, size_t len);
0023
0024 static int crct10dif_init(struct shash_desc *desc)
0025 {
0026 u16 *crc = shash_desc_ctx(desc);
0027
0028 *crc = 0;
0029 return 0;
0030 }
0031
0032 static int crct10dif_update(struct shash_desc *desc, const u8 *data,
0033 unsigned int length)
0034 {
0035 u16 *crc = shash_desc_ctx(desc);
0036
0037 if (length >= CRC_T10DIF_PMULL_CHUNK_SIZE && crypto_simd_usable()) {
0038 kernel_neon_begin();
0039 *crc = crc_t10dif_pmull(*crc, data, length);
0040 kernel_neon_end();
0041 } else {
0042 *crc = crc_t10dif_generic(*crc, data, length);
0043 }
0044
0045 return 0;
0046 }
0047
0048 static int crct10dif_final(struct shash_desc *desc, u8 *out)
0049 {
0050 u16 *crc = shash_desc_ctx(desc);
0051
0052 *(u16 *)out = *crc;
0053 return 0;
0054 }
0055
0056 static struct shash_alg crc_t10dif_alg = {
0057 .digestsize = CRC_T10DIF_DIGEST_SIZE,
0058 .init = crct10dif_init,
0059 .update = crct10dif_update,
0060 .final = crct10dif_final,
0061 .descsize = CRC_T10DIF_DIGEST_SIZE,
0062
0063 .base.cra_name = "crct10dif",
0064 .base.cra_driver_name = "crct10dif-arm-ce",
0065 .base.cra_priority = 200,
0066 .base.cra_blocksize = CRC_T10DIF_BLOCK_SIZE,
0067 .base.cra_module = THIS_MODULE,
0068 };
0069
0070 static int __init crc_t10dif_mod_init(void)
0071 {
0072 if (!(elf_hwcap2 & HWCAP2_PMULL))
0073 return -ENODEV;
0074
0075 return crypto_register_shash(&crc_t10dif_alg);
0076 }
0077
0078 static void __exit crc_t10dif_mod_exit(void)
0079 {
0080 crypto_unregister_shash(&crc_t10dif_alg);
0081 }
0082
0083 module_init(crc_t10dif_mod_init);
0084 module_exit(crc_t10dif_mod_exit);
0085
0086 MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
0087 MODULE_LICENSE("GPL v2");
0088 MODULE_ALIAS_CRYPTO("crct10dif");