xref: /linux/arch/s390/crypto/sha3_256_s390.c (revision 0d2ab5f922e75d10162e7199826e14df9cfae5cc)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Cryptographic API.
4  *
5  * s390 implementation of the SHA256 and SHA224 Secure Hash Algorithm.
6  *
7  * s390 Version:
8  *   Copyright IBM Corp. 2019
9  *   Author(s): Joerg Schmidbauer (jschmidb@de.ibm.com)
10  */
11 #include <asm/cpacf.h>
12 #include <crypto/internal/hash.h>
13 #include <crypto/sha3.h>
14 #include <linux/cpufeature.h>
15 #include <linux/errno.h>
16 #include <linux/kernel.h>
17 #include <linux/module.h>
18 #include <linux/string.h>
19 
20 #include "sha.h"
21 
22 static int sha3_256_init(struct shash_desc *desc)
23 {
24 	struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
25 
26 	sctx->first_message_part = test_facility(86);
27 	if (!sctx->first_message_part)
28 		memset(sctx->state, 0, sizeof(sctx->state));
29 	sctx->count = 0;
30 	sctx->func = CPACF_KIMD_SHA3_256;
31 
32 	return 0;
33 }
34 
35 static int sha3_256_export(struct shash_desc *desc, void *out)
36 {
37 	struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
38 	union {
39 		u8 *u8;
40 		u64 *u64;
41 	} p = { .u8 = out };
42 	int i;
43 
44 	if (sctx->first_message_part) {
45 		memset(out, 0, SHA3_STATE_SIZE);
46 		return 0;
47 	}
48 	for (i = 0; i < SHA3_STATE_SIZE / 8; i++)
49 		put_unaligned(le64_to_cpu(sctx->sha3.state[i]), p.u64++);
50 	return 0;
51 }
52 
53 static int sha3_256_import(struct shash_desc *desc, const void *in)
54 {
55 	struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
56 	union {
57 		const u8 *u8;
58 		const u64 *u64;
59 	} p = { .u8 = in };
60 	int i;
61 
62 	for (i = 0; i < SHA3_STATE_SIZE / 8; i++)
63 		sctx->sha3.state[i] = cpu_to_le64(get_unaligned(p.u64++));
64 	sctx->count = 0;
65 	sctx->first_message_part = 0;
66 	sctx->func = CPACF_KIMD_SHA3_256;
67 
68 	return 0;
69 }
70 
71 static int sha3_224_import(struct shash_desc *desc, const void *in)
72 {
73 	struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
74 
75 	sha3_256_import(desc, in);
76 	sctx->func = CPACF_KIMD_SHA3_224;
77 	return 0;
78 }
79 
80 static struct shash_alg sha3_256_alg = {
81 	.digestsize	=	SHA3_256_DIGEST_SIZE,	   /* = 32 */
82 	.init		=	sha3_256_init,
83 	.update		=	s390_sha_update_blocks,
84 	.finup		=	s390_sha_finup,
85 	.export		=	sha3_256_export,
86 	.import		=	sha3_256_import,
87 	.descsize	=	S390_SHA_CTX_SIZE,
88 	.statesize	=	SHA3_STATE_SIZE,
89 	.base		=	{
90 		.cra_name	 =	"sha3-256",
91 		.cra_driver_name =	"sha3-256-s390",
92 		.cra_priority	 =	300,
93 		.cra_flags	 =	CRYPTO_AHASH_ALG_BLOCK_ONLY,
94 		.cra_blocksize	 =	SHA3_256_BLOCK_SIZE,
95 		.cra_module	 =	THIS_MODULE,
96 	}
97 };
98 
99 static int sha3_224_init(struct shash_desc *desc)
100 {
101 	struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
102 
103 	sha3_256_init(desc);
104 	sctx->func = CPACF_KIMD_SHA3_224;
105 	return 0;
106 }
107 
108 static struct shash_alg sha3_224_alg = {
109 	.digestsize	=	SHA3_224_DIGEST_SIZE,
110 	.init		=	sha3_224_init,
111 	.update		=	s390_sha_update_blocks,
112 	.finup		=	s390_sha_finup,
113 	.export		=	sha3_256_export, /* same as for 256 */
114 	.import		=	sha3_224_import, /* function code different! */
115 	.descsize	=	S390_SHA_CTX_SIZE,
116 	.statesize	=	SHA3_STATE_SIZE,
117 	.base		=	{
118 		.cra_name	 =	"sha3-224",
119 		.cra_driver_name =	"sha3-224-s390",
120 		.cra_priority	 =	300,
121 		.cra_flags	 =	CRYPTO_AHASH_ALG_BLOCK_ONLY,
122 		.cra_blocksize	 =	SHA3_224_BLOCK_SIZE,
123 		.cra_module	 =	THIS_MODULE,
124 	}
125 };
126 
127 static int __init sha3_256_s390_init(void)
128 {
129 	int ret;
130 
131 	if (!cpacf_query_func(CPACF_KIMD, CPACF_KIMD_SHA3_256))
132 		return -ENODEV;
133 
134 	ret = crypto_register_shash(&sha3_256_alg);
135 	if (ret < 0)
136 		goto out;
137 
138 	ret = crypto_register_shash(&sha3_224_alg);
139 	if (ret < 0)
140 		crypto_unregister_shash(&sha3_256_alg);
141 out:
142 	return ret;
143 }
144 
145 static void __exit sha3_256_s390_fini(void)
146 {
147 	crypto_unregister_shash(&sha3_224_alg);
148 	crypto_unregister_shash(&sha3_256_alg);
149 }
150 
151 module_cpu_feature_match(S390_CPU_FEATURE_MSA, sha3_256_s390_init);
152 module_exit(sha3_256_s390_fini);
153 
154 MODULE_ALIAS_CRYPTO("sha3-256");
155 MODULE_ALIAS_CRYPTO("sha3-224");
156 MODULE_LICENSE("GPL");
157 MODULE_DESCRIPTION("SHA3-256 and SHA3-224 Secure Hash Algorithm");
158