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