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