1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2c80ae7caSArd Biesheuvel /*
3c80ae7caSArd Biesheuvel * sha512-glue.c - accelerated SHA-384/512 for ARM
4c80ae7caSArd Biesheuvel *
5c80ae7caSArd Biesheuvel * Copyright (C) 2015 Linaro Ltd <ard.biesheuvel@linaro.org>
6c80ae7caSArd Biesheuvel */
7c80ae7caSArd Biesheuvel
8c80ae7caSArd Biesheuvel #include <crypto/internal/hash.h>
9a24d22b2SEric Biggers #include <crypto/sha2.h>
10c80ae7caSArd Biesheuvel #include <crypto/sha512_base.h>
11c80ae7caSArd Biesheuvel #include <linux/crypto.h>
12c80ae7caSArd Biesheuvel #include <linux/module.h>
13c80ae7caSArd Biesheuvel
14c80ae7caSArd Biesheuvel #include <asm/hwcap.h>
15c80ae7caSArd Biesheuvel #include <asm/neon.h>
16c80ae7caSArd Biesheuvel
17c80ae7caSArd Biesheuvel #include "sha512.h"
18c80ae7caSArd Biesheuvel
19c80ae7caSArd Biesheuvel MODULE_DESCRIPTION("Accelerated SHA-384/SHA-512 secure hash for ARM");
20c80ae7caSArd Biesheuvel MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
21c80ae7caSArd Biesheuvel MODULE_LICENSE("GPL v2");
22c80ae7caSArd Biesheuvel
23c80ae7caSArd Biesheuvel MODULE_ALIAS_CRYPTO("sha384");
24c80ae7caSArd Biesheuvel MODULE_ALIAS_CRYPTO("sha512");
25c80ae7caSArd Biesheuvel MODULE_ALIAS_CRYPTO("sha384-arm");
26c80ae7caSArd Biesheuvel MODULE_ALIAS_CRYPTO("sha512-arm");
27c80ae7caSArd Biesheuvel
28*7baf1151SArnd Bergmann asmlinkage void sha512_block_data_order(struct sha512_state *state,
29*7baf1151SArnd Bergmann u8 const *src, int blocks);
30c80ae7caSArd Biesheuvel
sha512_arm_update(struct shash_desc * desc,const u8 * data,unsigned int len)31c80ae7caSArd Biesheuvel int sha512_arm_update(struct shash_desc *desc, const u8 *data,
32c80ae7caSArd Biesheuvel unsigned int len)
33c80ae7caSArd Biesheuvel {
34*7baf1151SArnd Bergmann return sha512_base_do_update(desc, data, len, sha512_block_data_order);
35c80ae7caSArd Biesheuvel }
36c80ae7caSArd Biesheuvel
sha512_arm_final(struct shash_desc * desc,u8 * out)37efc77e81SYueHaibing static int sha512_arm_final(struct shash_desc *desc, u8 *out)
38c80ae7caSArd Biesheuvel {
39*7baf1151SArnd Bergmann sha512_base_do_finalize(desc, sha512_block_data_order);
40c80ae7caSArd Biesheuvel return sha512_base_finish(desc, out);
41c80ae7caSArd Biesheuvel }
42c80ae7caSArd Biesheuvel
sha512_arm_finup(struct shash_desc * desc,const u8 * data,unsigned int len,u8 * out)43c80ae7caSArd Biesheuvel int sha512_arm_finup(struct shash_desc *desc, const u8 *data,
44c80ae7caSArd Biesheuvel unsigned int len, u8 *out)
45c80ae7caSArd Biesheuvel {
46*7baf1151SArnd Bergmann sha512_base_do_update(desc, data, len, sha512_block_data_order);
47c80ae7caSArd Biesheuvel return sha512_arm_final(desc, out);
48c80ae7caSArd Biesheuvel }
49c80ae7caSArd Biesheuvel
50c80ae7caSArd Biesheuvel static struct shash_alg sha512_arm_algs[] = { {
51c80ae7caSArd Biesheuvel .init = sha384_base_init,
52c80ae7caSArd Biesheuvel .update = sha512_arm_update,
53c80ae7caSArd Biesheuvel .final = sha512_arm_final,
54c80ae7caSArd Biesheuvel .finup = sha512_arm_finup,
55c80ae7caSArd Biesheuvel .descsize = sizeof(struct sha512_state),
56c80ae7caSArd Biesheuvel .digestsize = SHA384_DIGEST_SIZE,
57c80ae7caSArd Biesheuvel .base = {
58c80ae7caSArd Biesheuvel .cra_name = "sha384",
59c80ae7caSArd Biesheuvel .cra_driver_name = "sha384-arm",
60c80ae7caSArd Biesheuvel .cra_priority = 250,
61c80ae7caSArd Biesheuvel .cra_blocksize = SHA512_BLOCK_SIZE,
62c80ae7caSArd Biesheuvel .cra_module = THIS_MODULE,
63c80ae7caSArd Biesheuvel }
64c80ae7caSArd Biesheuvel }, {
65c80ae7caSArd Biesheuvel .init = sha512_base_init,
66c80ae7caSArd Biesheuvel .update = sha512_arm_update,
67c80ae7caSArd Biesheuvel .final = sha512_arm_final,
68c80ae7caSArd Biesheuvel .finup = sha512_arm_finup,
69c80ae7caSArd Biesheuvel .descsize = sizeof(struct sha512_state),
70c80ae7caSArd Biesheuvel .digestsize = SHA512_DIGEST_SIZE,
71c80ae7caSArd Biesheuvel .base = {
72c80ae7caSArd Biesheuvel .cra_name = "sha512",
73c80ae7caSArd Biesheuvel .cra_driver_name = "sha512-arm",
74c80ae7caSArd Biesheuvel .cra_priority = 250,
75c80ae7caSArd Biesheuvel .cra_blocksize = SHA512_BLOCK_SIZE,
76c80ae7caSArd Biesheuvel .cra_module = THIS_MODULE,
77c80ae7caSArd Biesheuvel }
78c80ae7caSArd Biesheuvel } };
79c80ae7caSArd Biesheuvel
sha512_arm_mod_init(void)80c80ae7caSArd Biesheuvel static int __init sha512_arm_mod_init(void)
81c80ae7caSArd Biesheuvel {
82c80ae7caSArd Biesheuvel int err;
83c80ae7caSArd Biesheuvel
84c80ae7caSArd Biesheuvel err = crypto_register_shashes(sha512_arm_algs,
85c80ae7caSArd Biesheuvel ARRAY_SIZE(sha512_arm_algs));
86c80ae7caSArd Biesheuvel if (err)
87c80ae7caSArd Biesheuvel return err;
88c80ae7caSArd Biesheuvel
89c80ae7caSArd Biesheuvel if (IS_ENABLED(CONFIG_KERNEL_MODE_NEON) && cpu_has_neon()) {
90c80ae7caSArd Biesheuvel err = crypto_register_shashes(sha512_neon_algs,
91c80ae7caSArd Biesheuvel ARRAY_SIZE(sha512_neon_algs));
92c80ae7caSArd Biesheuvel if (err)
93c80ae7caSArd Biesheuvel goto err_unregister;
94c80ae7caSArd Biesheuvel }
95c80ae7caSArd Biesheuvel return 0;
96c80ae7caSArd Biesheuvel
97c80ae7caSArd Biesheuvel err_unregister:
98c80ae7caSArd Biesheuvel crypto_unregister_shashes(sha512_arm_algs,
99c80ae7caSArd Biesheuvel ARRAY_SIZE(sha512_arm_algs));
100c80ae7caSArd Biesheuvel
101c80ae7caSArd Biesheuvel return err;
102c80ae7caSArd Biesheuvel }
103c80ae7caSArd Biesheuvel
sha512_arm_mod_fini(void)104c80ae7caSArd Biesheuvel static void __exit sha512_arm_mod_fini(void)
105c80ae7caSArd Biesheuvel {
106c80ae7caSArd Biesheuvel crypto_unregister_shashes(sha512_arm_algs,
107c80ae7caSArd Biesheuvel ARRAY_SIZE(sha512_arm_algs));
108c80ae7caSArd Biesheuvel if (IS_ENABLED(CONFIG_KERNEL_MODE_NEON) && cpu_has_neon())
109c80ae7caSArd Biesheuvel crypto_unregister_shashes(sha512_neon_algs,
110c80ae7caSArd Biesheuvel ARRAY_SIZE(sha512_neon_algs));
111c80ae7caSArd Biesheuvel }
112c80ae7caSArd Biesheuvel
113c80ae7caSArd Biesheuvel module_init(sha512_arm_mod_init);
114c80ae7caSArd Biesheuvel module_exit(sha512_arm_mod_fini);
115