0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <crypto/internal/hash.h>
0010 #include <crypto/internal/simd.h>
0011 #include <crypto/nhpoly1305.h>
0012 #include <linux/module.h>
0013 #include <linux/sizes.h>
0014 #include <asm/simd.h>
0015
0016 asmlinkage void nh_sse2(const u32 *key, const u8 *message, size_t message_len,
0017 u8 hash[NH_HASH_BYTES]);
0018
0019
0020 static void _nh_sse2(const u32 *key, const u8 *message, size_t message_len,
0021 __le64 hash[NH_NUM_PASSES])
0022 {
0023 nh_sse2(key, message, message_len, (u8 *)hash);
0024 }
0025
0026 static int nhpoly1305_sse2_update(struct shash_desc *desc,
0027 const u8 *src, unsigned int srclen)
0028 {
0029 if (srclen < 64 || !crypto_simd_usable())
0030 return crypto_nhpoly1305_update(desc, src, srclen);
0031
0032 do {
0033 unsigned int n = min_t(unsigned int, srclen, SZ_4K);
0034
0035 kernel_fpu_begin();
0036 crypto_nhpoly1305_update_helper(desc, src, n, _nh_sse2);
0037 kernel_fpu_end();
0038 src += n;
0039 srclen -= n;
0040 } while (srclen);
0041 return 0;
0042 }
0043
0044 static struct shash_alg nhpoly1305_alg = {
0045 .base.cra_name = "nhpoly1305",
0046 .base.cra_driver_name = "nhpoly1305-sse2",
0047 .base.cra_priority = 200,
0048 .base.cra_ctxsize = sizeof(struct nhpoly1305_key),
0049 .base.cra_module = THIS_MODULE,
0050 .digestsize = POLY1305_DIGEST_SIZE,
0051 .init = crypto_nhpoly1305_init,
0052 .update = nhpoly1305_sse2_update,
0053 .final = crypto_nhpoly1305_final,
0054 .setkey = crypto_nhpoly1305_setkey,
0055 .descsize = sizeof(struct nhpoly1305_state),
0056 };
0057
0058 static int __init nhpoly1305_mod_init(void)
0059 {
0060 if (!boot_cpu_has(X86_FEATURE_XMM2))
0061 return -ENODEV;
0062
0063 return crypto_register_shash(&nhpoly1305_alg);
0064 }
0065
0066 static void __exit nhpoly1305_mod_exit(void)
0067 {
0068 crypto_unregister_shash(&nhpoly1305_alg);
0069 }
0070
0071 module_init(nhpoly1305_mod_init);
0072 module_exit(nhpoly1305_mod_exit);
0073
0074 MODULE_DESCRIPTION("NHPoly1305 ε-almost-∆-universal hash function (SSE2-accelerated)");
0075 MODULE_LICENSE("GPL v2");
0076 MODULE_AUTHOR("Eric Biggers <ebiggers@google.com>");
0077 MODULE_ALIAS_CRYPTO("nhpoly1305");
0078 MODULE_ALIAS_CRYPTO("nhpoly1305-sse2");