12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2f2f770d7SSami Tolvanen /*
3f2f770d7SSami Tolvanen * Glue code for the SHA256 Secure Hash Algorithm assembly implementation
4f2f770d7SSami Tolvanen * using optimized ARM assembler and NEON instructions.
5f2f770d7SSami Tolvanen *
63723c632SArnd Bergmann * Copyright © 2015 Google Inc.
7f2f770d7SSami Tolvanen *
8f2f770d7SSami Tolvanen * This file is based on sha256_ssse3_glue.c:
9f2f770d7SSami Tolvanen * Copyright (C) 2013 Intel Corporation
10f2f770d7SSami Tolvanen * Author: Tim Chen <tim.c.chen@linux.intel.com>
11f2f770d7SSami Tolvanen */
12f2f770d7SSami Tolvanen
13f2f770d7SSami Tolvanen #include <crypto/internal/hash.h>
14f2f770d7SSami Tolvanen #include <linux/crypto.h>
15f2f770d7SSami Tolvanen #include <linux/init.h>
16f2f770d7SSami Tolvanen #include <linux/module.h>
17f2f770d7SSami Tolvanen #include <linux/mm.h>
18f2f770d7SSami Tolvanen #include <linux/types.h>
19f2f770d7SSami Tolvanen #include <linux/string.h>
20a24d22b2SEric Biggers #include <crypto/sha2.h>
21b59e2ae3SArd Biesheuvel #include <crypto/sha256_base.h>
22f2f770d7SSami Tolvanen #include <asm/simd.h>
23f2f770d7SSami Tolvanen #include <asm/neon.h>
24b59e2ae3SArd Biesheuvel
25f2f770d7SSami Tolvanen #include "sha256_glue.h"
26f2f770d7SSami Tolvanen
27*7baf1151SArnd Bergmann asmlinkage void sha256_block_data_order(struct sha256_state *state,
28*7baf1151SArnd Bergmann const u8 *data, int num_blks);
29f2f770d7SSami Tolvanen
crypto_sha256_arm_update(struct shash_desc * desc,const u8 * data,unsigned int len)30b59e2ae3SArd Biesheuvel int crypto_sha256_arm_update(struct shash_desc *desc, const u8 *data,
31b59e2ae3SArd Biesheuvel unsigned int len)
32f2f770d7SSami Tolvanen {
33b59e2ae3SArd Biesheuvel /* make sure casting to sha256_block_fn() is safe */
34b59e2ae3SArd Biesheuvel BUILD_BUG_ON(offsetof(struct sha256_state, state) != 0);
35f2f770d7SSami Tolvanen
36*7baf1151SArnd Bergmann return sha256_base_do_update(desc, data, len, sha256_block_data_order);
37f2f770d7SSami Tolvanen }
38b59e2ae3SArd Biesheuvel EXPORT_SYMBOL(crypto_sha256_arm_update);
39f2f770d7SSami Tolvanen
crypto_sha256_arm_final(struct shash_desc * desc,u8 * out)40e4dcc1beSHans de Goede static int crypto_sha256_arm_final(struct shash_desc *desc, u8 *out)
41f2f770d7SSami Tolvanen {
42*7baf1151SArnd Bergmann sha256_base_do_finalize(desc, sha256_block_data_order);
43b59e2ae3SArd Biesheuvel return sha256_base_finish(desc, out);
44f2f770d7SSami Tolvanen }
45f2f770d7SSami Tolvanen
crypto_sha256_arm_finup(struct shash_desc * desc,const u8 * data,unsigned int len,u8 * out)46b59e2ae3SArd Biesheuvel int crypto_sha256_arm_finup(struct shash_desc *desc, const u8 *data,
47b59e2ae3SArd Biesheuvel unsigned int len, u8 *out)
48f2f770d7SSami Tolvanen {
49*7baf1151SArnd Bergmann sha256_base_do_update(desc, data, len, sha256_block_data_order);
50e4dcc1beSHans de Goede return crypto_sha256_arm_final(desc, out);
51f2f770d7SSami Tolvanen }
52b59e2ae3SArd Biesheuvel EXPORT_SYMBOL(crypto_sha256_arm_finup);
53f2f770d7SSami Tolvanen
54f2f770d7SSami Tolvanen static struct shash_alg algs[] = { {
55f2f770d7SSami Tolvanen .digestsize = SHA256_DIGEST_SIZE,
56b59e2ae3SArd Biesheuvel .init = sha256_base_init,
57b59e2ae3SArd Biesheuvel .update = crypto_sha256_arm_update,
58e4dcc1beSHans de Goede .final = crypto_sha256_arm_final,
59b59e2ae3SArd Biesheuvel .finup = crypto_sha256_arm_finup,
60f2f770d7SSami Tolvanen .descsize = sizeof(struct sha256_state),
61f2f770d7SSami Tolvanen .base = {
62f2f770d7SSami Tolvanen .cra_name = "sha256",
63f2f770d7SSami Tolvanen .cra_driver_name = "sha256-asm",
64f2f770d7SSami Tolvanen .cra_priority = 150,
65f2f770d7SSami Tolvanen .cra_blocksize = SHA256_BLOCK_SIZE,
66f2f770d7SSami Tolvanen .cra_module = THIS_MODULE,
67f2f770d7SSami Tolvanen }
68f2f770d7SSami Tolvanen }, {
69f2f770d7SSami Tolvanen .digestsize = SHA224_DIGEST_SIZE,
70b59e2ae3SArd Biesheuvel .init = sha224_base_init,
71b59e2ae3SArd Biesheuvel .update = crypto_sha256_arm_update,
72e4dcc1beSHans de Goede .final = crypto_sha256_arm_final,
73b59e2ae3SArd Biesheuvel .finup = crypto_sha256_arm_finup,
74f2f770d7SSami Tolvanen .descsize = sizeof(struct sha256_state),
75f2f770d7SSami Tolvanen .base = {
76f2f770d7SSami Tolvanen .cra_name = "sha224",
77f2f770d7SSami Tolvanen .cra_driver_name = "sha224-asm",
78f2f770d7SSami Tolvanen .cra_priority = 150,
79f2f770d7SSami Tolvanen .cra_blocksize = SHA224_BLOCK_SIZE,
80f2f770d7SSami Tolvanen .cra_module = THIS_MODULE,
81f2f770d7SSami Tolvanen }
82f2f770d7SSami Tolvanen } };
83f2f770d7SSami Tolvanen
sha256_mod_init(void)84f2f770d7SSami Tolvanen static int __init sha256_mod_init(void)
85f2f770d7SSami Tolvanen {
86f2f770d7SSami Tolvanen int res = crypto_register_shashes(algs, ARRAY_SIZE(algs));
87f2f770d7SSami Tolvanen
88f2f770d7SSami Tolvanen if (res < 0)
89f2f770d7SSami Tolvanen return res;
90f2f770d7SSami Tolvanen
91f2f770d7SSami Tolvanen if (IS_ENABLED(CONFIG_KERNEL_MODE_NEON) && cpu_has_neon()) {
92f2f770d7SSami Tolvanen res = crypto_register_shashes(sha256_neon_algs,
93f2f770d7SSami Tolvanen ARRAY_SIZE(sha256_neon_algs));
94f2f770d7SSami Tolvanen
95f2f770d7SSami Tolvanen if (res < 0)
96f2f770d7SSami Tolvanen crypto_unregister_shashes(algs, ARRAY_SIZE(algs));
97f2f770d7SSami Tolvanen }
98f2f770d7SSami Tolvanen
99f2f770d7SSami Tolvanen return res;
100f2f770d7SSami Tolvanen }
101f2f770d7SSami Tolvanen
sha256_mod_fini(void)102f2f770d7SSami Tolvanen static void __exit sha256_mod_fini(void)
103f2f770d7SSami Tolvanen {
104f2f770d7SSami Tolvanen crypto_unregister_shashes(algs, ARRAY_SIZE(algs));
105f2f770d7SSami Tolvanen
106f2f770d7SSami Tolvanen if (IS_ENABLED(CONFIG_KERNEL_MODE_NEON) && cpu_has_neon())
107f2f770d7SSami Tolvanen crypto_unregister_shashes(sha256_neon_algs,
108f2f770d7SSami Tolvanen ARRAY_SIZE(sha256_neon_algs));
109f2f770d7SSami Tolvanen }
110f2f770d7SSami Tolvanen
111f2f770d7SSami Tolvanen module_init(sha256_mod_init);
112f2f770d7SSami Tolvanen module_exit(sha256_mod_fini);
113f2f770d7SSami Tolvanen
114f2f770d7SSami Tolvanen MODULE_LICENSE("GPL");
115f2f770d7SSami Tolvanen MODULE_DESCRIPTION("SHA256 Secure Hash Algorithm (ARM), including NEON");
116f2f770d7SSami Tolvanen
117f2f770d7SSami Tolvanen MODULE_ALIAS_CRYPTO("sha256");
118