xref: /linux/arch/s390/crypto/sha3_256_s390.c (revision 3a39d672e7f48b8d6b91a09afa4b55352773b4b5)
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 <crypto/internal/hash.h>
12 #include <linux/init.h>
13 #include <linux/module.h>
14 #include <linux/cpufeature.h>
15 #include <crypto/sha3.h>
16 #include <asm/cpacf.h>
17 
18 #include "sha.h"
19 
sha3_256_init(struct shash_desc * desc)20 static int sha3_256_init(struct shash_desc *desc)
21 {
22 	struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
23 
24 	if (!test_facility(86)) /* msa 12 */
25 		memset(sctx->state, 0, sizeof(sctx->state));
26 	sctx->count = 0;
27 	sctx->func = CPACF_KIMD_SHA3_256;
28 	sctx->first_message_part = 1;
29 
30 	return 0;
31 }
32 
sha3_256_export(struct shash_desc * desc,void * out)33 static int sha3_256_export(struct shash_desc *desc, void *out)
34 {
35 	struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
36 	struct sha3_state *octx = out;
37 
38 	octx->rsiz = sctx->count;
39 	memcpy(octx->st, sctx->state, sizeof(octx->st));
40 	memcpy(octx->buf, sctx->buf, sizeof(octx->buf));
41 	octx->partial = sctx->first_message_part;
42 
43 	return 0;
44 }
45 
sha3_256_import(struct shash_desc * desc,const void * in)46 static int sha3_256_import(struct shash_desc *desc, const void *in)
47 {
48 	struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
49 	const struct sha3_state *ictx = in;
50 
51 	sctx->count = ictx->rsiz;
52 	memcpy(sctx->state, ictx->st, sizeof(ictx->st));
53 	memcpy(sctx->buf, ictx->buf, sizeof(ictx->buf));
54 	sctx->first_message_part = ictx->partial;
55 	sctx->func = CPACF_KIMD_SHA3_256;
56 
57 	return 0;
58 }
59 
sha3_224_import(struct shash_desc * desc,const void * in)60 static int sha3_224_import(struct shash_desc *desc, const void *in)
61 {
62 	struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
63 	const struct sha3_state *ictx = in;
64 
65 	sctx->count = ictx->rsiz;
66 	memcpy(sctx->state, ictx->st, sizeof(ictx->st));
67 	memcpy(sctx->buf, ictx->buf, sizeof(ictx->buf));
68 	sctx->first_message_part = ictx->partial;
69 	sctx->func = CPACF_KIMD_SHA3_224;
70 
71 	return 0;
72 }
73 
74 static struct shash_alg sha3_256_alg = {
75 	.digestsize	=	SHA3_256_DIGEST_SIZE,	   /* = 32 */
76 	.init		=	sha3_256_init,
77 	.update		=	s390_sha_update,
78 	.final		=	s390_sha_final,
79 	.export		=	sha3_256_export,
80 	.import		=	sha3_256_import,
81 	.descsize	=	sizeof(struct s390_sha_ctx),
82 	.statesize	=	sizeof(struct sha3_state),
83 	.base		=	{
84 		.cra_name	 =	"sha3-256",
85 		.cra_driver_name =	"sha3-256-s390",
86 		.cra_priority	 =	300,
87 		.cra_blocksize	 =	SHA3_256_BLOCK_SIZE,
88 		.cra_module	 =	THIS_MODULE,
89 	}
90 };
91 
sha3_224_init(struct shash_desc * desc)92 static int sha3_224_init(struct shash_desc *desc)
93 {
94 	struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
95 
96 	if (!test_facility(86)) /* msa 12 */
97 		memset(sctx->state, 0, sizeof(sctx->state));
98 	sctx->count = 0;
99 	sctx->func = CPACF_KIMD_SHA3_224;
100 	sctx->first_message_part = 1;
101 
102 	return 0;
103 }
104 
105 static struct shash_alg sha3_224_alg = {
106 	.digestsize	=	SHA3_224_DIGEST_SIZE,
107 	.init		=	sha3_224_init,
108 	.update		=	s390_sha_update,
109 	.final		=	s390_sha_final,
110 	.export		=	sha3_256_export, /* same as for 256 */
111 	.import		=	sha3_224_import, /* function code different! */
112 	.descsize	=	sizeof(struct s390_sha_ctx),
113 	.statesize	=	sizeof(struct sha3_state),
114 	.base		=	{
115 		.cra_name	 =	"sha3-224",
116 		.cra_driver_name =	"sha3-224-s390",
117 		.cra_priority	 =	300,
118 		.cra_blocksize	 =	SHA3_224_BLOCK_SIZE,
119 		.cra_module	 =	THIS_MODULE,
120 	}
121 };
122 
sha3_256_s390_init(void)123 static int __init sha3_256_s390_init(void)
124 {
125 	int ret;
126 
127 	if (!cpacf_query_func(CPACF_KIMD, CPACF_KIMD_SHA3_256))
128 		return -ENODEV;
129 
130 	ret = crypto_register_shash(&sha3_256_alg);
131 	if (ret < 0)
132 		goto out;
133 
134 	ret = crypto_register_shash(&sha3_224_alg);
135 	if (ret < 0)
136 		crypto_unregister_shash(&sha3_256_alg);
137 out:
138 	return ret;
139 }
140 
sha3_256_s390_fini(void)141 static void __exit sha3_256_s390_fini(void)
142 {
143 	crypto_unregister_shash(&sha3_224_alg);
144 	crypto_unregister_shash(&sha3_256_alg);
145 }
146 
147 module_cpu_feature_match(S390_CPU_FEATURE_MSA, sha3_256_s390_init);
148 module_exit(sha3_256_s390_fini);
149 
150 MODULE_ALIAS_CRYPTO("sha3-256");
151 MODULE_ALIAS_CRYPTO("sha3-224");
152 MODULE_LICENSE("GPL");
153 MODULE_DESCRIPTION("SHA3-256 and SHA3-224 Secure Hash Algorithm");
154