Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * sha1-ce-glue.c - SHA-1 secure hash using ARMv8 Crypto Extensions
0004  *
0005  * Copyright (C) 2015 Linaro Ltd <ard.biesheuvel@linaro.org>
0006  */
0007 
0008 #include <crypto/internal/hash.h>
0009 #include <crypto/internal/simd.h>
0010 #include <crypto/sha1.h>
0011 #include <crypto/sha1_base.h>
0012 #include <linux/cpufeature.h>
0013 #include <linux/crypto.h>
0014 #include <linux/module.h>
0015 
0016 #include <asm/hwcap.h>
0017 #include <asm/neon.h>
0018 #include <asm/simd.h>
0019 
0020 #include "sha1.h"
0021 
0022 MODULE_DESCRIPTION("SHA1 secure hash using ARMv8 Crypto Extensions");
0023 MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
0024 MODULE_LICENSE("GPL v2");
0025 
0026 asmlinkage void sha1_ce_transform(struct sha1_state *sst, u8 const *src,
0027                   int blocks);
0028 
0029 static int sha1_ce_update(struct shash_desc *desc, const u8 *data,
0030               unsigned int len)
0031 {
0032     struct sha1_state *sctx = shash_desc_ctx(desc);
0033 
0034     if (!crypto_simd_usable() ||
0035         (sctx->count % SHA1_BLOCK_SIZE) + len < SHA1_BLOCK_SIZE)
0036         return sha1_update_arm(desc, data, len);
0037 
0038     kernel_neon_begin();
0039     sha1_base_do_update(desc, data, len, sha1_ce_transform);
0040     kernel_neon_end();
0041 
0042     return 0;
0043 }
0044 
0045 static int sha1_ce_finup(struct shash_desc *desc, const u8 *data,
0046              unsigned int len, u8 *out)
0047 {
0048     if (!crypto_simd_usable())
0049         return sha1_finup_arm(desc, data, len, out);
0050 
0051     kernel_neon_begin();
0052     if (len)
0053         sha1_base_do_update(desc, data, len, sha1_ce_transform);
0054     sha1_base_do_finalize(desc, sha1_ce_transform);
0055     kernel_neon_end();
0056 
0057     return sha1_base_finish(desc, out);
0058 }
0059 
0060 static int sha1_ce_final(struct shash_desc *desc, u8 *out)
0061 {
0062     return sha1_ce_finup(desc, NULL, 0, out);
0063 }
0064 
0065 static struct shash_alg alg = {
0066     .init           = sha1_base_init,
0067     .update         = sha1_ce_update,
0068     .final          = sha1_ce_final,
0069     .finup          = sha1_ce_finup,
0070     .descsize       = sizeof(struct sha1_state),
0071     .digestsize     = SHA1_DIGEST_SIZE,
0072     .base           = {
0073         .cra_name       = "sha1",
0074         .cra_driver_name    = "sha1-ce",
0075         .cra_priority       = 200,
0076         .cra_blocksize      = SHA1_BLOCK_SIZE,
0077         .cra_module     = THIS_MODULE,
0078     }
0079 };
0080 
0081 static int __init sha1_ce_mod_init(void)
0082 {
0083     return crypto_register_shash(&alg);
0084 }
0085 
0086 static void __exit sha1_ce_mod_fini(void)
0087 {
0088     crypto_unregister_shash(&alg);
0089 }
0090 
0091 module_cpu_feature_match(SHA1, sha1_ce_mod_init);
0092 module_exit(sha1_ce_mod_fini);