xref: /openbmc/linux/arch/arm/crypto/sha2-ce-glue.c (revision cdd38c5f1ce4398ec58fec95904b75824daab7b5)
1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2006d0624SArd Biesheuvel /*
3006d0624SArd Biesheuvel  * sha2-ce-glue.c - SHA-224/SHA-256 using ARMv8 Crypto Extensions
4006d0624SArd Biesheuvel  *
5006d0624SArd Biesheuvel  * Copyright (C) 2015 Linaro Ltd <ard.biesheuvel@linaro.org>
6006d0624SArd Biesheuvel  */
7006d0624SArd Biesheuvel 
8006d0624SArd Biesheuvel #include <crypto/internal/hash.h>
999680c5eSEric Biggers #include <crypto/internal/simd.h>
10*a24d22b2SEric Biggers #include <crypto/sha2.h>
119205b949SArd Biesheuvel #include <crypto/sha256_base.h>
12a83ff88bSArd Biesheuvel #include <linux/cpufeature.h>
13006d0624SArd Biesheuvel #include <linux/crypto.h>
14006d0624SArd Biesheuvel #include <linux/module.h>
15006d0624SArd Biesheuvel 
16006d0624SArd Biesheuvel #include <asm/hwcap.h>
17006d0624SArd Biesheuvel #include <asm/simd.h>
18006d0624SArd Biesheuvel #include <asm/neon.h>
19006d0624SArd Biesheuvel #include <asm/unaligned.h>
20006d0624SArd Biesheuvel 
219205b949SArd Biesheuvel #include "sha256_glue.h"
229205b949SArd Biesheuvel 
23006d0624SArd Biesheuvel MODULE_DESCRIPTION("SHA-224/SHA-256 secure hash using ARMv8 Crypto Extensions");
24006d0624SArd Biesheuvel MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
25006d0624SArd Biesheuvel MODULE_LICENSE("GPL v2");
26006d0624SArd Biesheuvel 
279205b949SArd Biesheuvel asmlinkage void sha2_ce_transform(struct sha256_state *sst, u8 const *src,
289205b949SArd Biesheuvel 				  int blocks);
29006d0624SArd Biesheuvel 
sha2_ce_update(struct shash_desc * desc,const u8 * data,unsigned int len)309205b949SArd Biesheuvel static int sha2_ce_update(struct shash_desc *desc, const u8 *data,
31006d0624SArd Biesheuvel 			  unsigned int len)
32006d0624SArd Biesheuvel {
33006d0624SArd Biesheuvel 	struct sha256_state *sctx = shash_desc_ctx(desc);
34006d0624SArd Biesheuvel 
3599680c5eSEric Biggers 	if (!crypto_simd_usable() ||
369205b949SArd Biesheuvel 	    (sctx->count % SHA256_BLOCK_SIZE) + len < SHA256_BLOCK_SIZE)
379205b949SArd Biesheuvel 		return crypto_sha256_arm_update(desc, data, len);
38006d0624SArd Biesheuvel 
39006d0624SArd Biesheuvel 	kernel_neon_begin();
409205b949SArd Biesheuvel 	sha256_base_do_update(desc, data, len,
419205b949SArd Biesheuvel 			      (sha256_block_fn *)sha2_ce_transform);
42006d0624SArd Biesheuvel 	kernel_neon_end();
43006d0624SArd Biesheuvel 
449205b949SArd Biesheuvel 	return 0;
45006d0624SArd Biesheuvel }
469205b949SArd Biesheuvel 
sha2_ce_finup(struct shash_desc * desc,const u8 * data,unsigned int len,u8 * out)479205b949SArd Biesheuvel static int sha2_ce_finup(struct shash_desc *desc, const u8 *data,
489205b949SArd Biesheuvel 			 unsigned int len, u8 *out)
499205b949SArd Biesheuvel {
5099680c5eSEric Biggers 	if (!crypto_simd_usable())
519205b949SArd Biesheuvel 		return crypto_sha256_arm_finup(desc, data, len, out);
529205b949SArd Biesheuvel 
539205b949SArd Biesheuvel 	kernel_neon_begin();
54006d0624SArd Biesheuvel 	if (len)
559205b949SArd Biesheuvel 		sha256_base_do_update(desc, data, len,
569205b949SArd Biesheuvel 				      (sha256_block_fn *)sha2_ce_transform);
579205b949SArd Biesheuvel 	sha256_base_do_finalize(desc, (sha256_block_fn *)sha2_ce_transform);
589205b949SArd Biesheuvel 	kernel_neon_end();
599205b949SArd Biesheuvel 
609205b949SArd Biesheuvel 	return sha256_base_finish(desc, out);
61006d0624SArd Biesheuvel }
62006d0624SArd Biesheuvel 
sha2_ce_final(struct shash_desc * desc,u8 * out)639205b949SArd Biesheuvel static int sha2_ce_final(struct shash_desc *desc, u8 *out)
64006d0624SArd Biesheuvel {
659205b949SArd Biesheuvel 	return sha2_ce_finup(desc, NULL, 0, out);
66006d0624SArd Biesheuvel }
67006d0624SArd Biesheuvel 
68006d0624SArd Biesheuvel static struct shash_alg algs[] = { {
699205b949SArd Biesheuvel 	.init			= sha224_base_init,
709205b949SArd Biesheuvel 	.update			= sha2_ce_update,
719205b949SArd Biesheuvel 	.final			= sha2_ce_final,
729205b949SArd Biesheuvel 	.finup			= sha2_ce_finup,
73006d0624SArd Biesheuvel 	.descsize		= sizeof(struct sha256_state),
74006d0624SArd Biesheuvel 	.digestsize		= SHA224_DIGEST_SIZE,
75006d0624SArd Biesheuvel 	.base			= {
76006d0624SArd Biesheuvel 		.cra_name		= "sha224",
77006d0624SArd Biesheuvel 		.cra_driver_name	= "sha224-ce",
78f2f770d7SSami Tolvanen 		.cra_priority		= 300,
79006d0624SArd Biesheuvel 		.cra_blocksize		= SHA256_BLOCK_SIZE,
80006d0624SArd Biesheuvel 		.cra_module		= THIS_MODULE,
81006d0624SArd Biesheuvel 	}
82006d0624SArd Biesheuvel }, {
839205b949SArd Biesheuvel 	.init			= sha256_base_init,
849205b949SArd Biesheuvel 	.update			= sha2_ce_update,
859205b949SArd Biesheuvel 	.final			= sha2_ce_final,
869205b949SArd Biesheuvel 	.finup			= sha2_ce_finup,
87006d0624SArd Biesheuvel 	.descsize		= sizeof(struct sha256_state),
88006d0624SArd Biesheuvel 	.digestsize		= SHA256_DIGEST_SIZE,
89006d0624SArd Biesheuvel 	.base			= {
90006d0624SArd Biesheuvel 		.cra_name		= "sha256",
91006d0624SArd Biesheuvel 		.cra_driver_name	= "sha256-ce",
92f2f770d7SSami Tolvanen 		.cra_priority		= 300,
93006d0624SArd Biesheuvel 		.cra_blocksize		= SHA256_BLOCK_SIZE,
94006d0624SArd Biesheuvel 		.cra_module		= THIS_MODULE,
95006d0624SArd Biesheuvel 	}
96006d0624SArd Biesheuvel } };
97006d0624SArd Biesheuvel 
sha2_ce_mod_init(void)98006d0624SArd Biesheuvel static int __init sha2_ce_mod_init(void)
99006d0624SArd Biesheuvel {
100006d0624SArd Biesheuvel 	return crypto_register_shashes(algs, ARRAY_SIZE(algs));
101006d0624SArd Biesheuvel }
102006d0624SArd Biesheuvel 
sha2_ce_mod_fini(void)103006d0624SArd Biesheuvel static void __exit sha2_ce_mod_fini(void)
104006d0624SArd Biesheuvel {
105006d0624SArd Biesheuvel 	crypto_unregister_shashes(algs, ARRAY_SIZE(algs));
106006d0624SArd Biesheuvel }
107006d0624SArd Biesheuvel 
108a83ff88bSArd Biesheuvel module_cpu_feature_match(SHA2, sha2_ce_mod_init);
109006d0624SArd Biesheuvel module_exit(sha2_ce_mod_fini);
110