]>
Commit | Line | Data |
---|---|---|
91ce87c0 | 1 | /* |
1212818e | 2 | * Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. |
91ce87c0 | 3 | * |
4a8b0c55 | 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
91ce87c0 AP |
5 | * this file except in compliance with the License. You can obtain a copy |
6 | * in the file LICENSE in the source distribution or at | |
7 | * https://www.openssl.org/source/license.html | |
8 | */ | |
9 | ||
10 | #include <stdio.h> | |
11 | #include <string.h> | |
12 | ||
13 | #include <openssl/evp.h> | |
14 | #include <openssl/objects.h> | |
15 | #include "internal/evp_int.h" | |
d5e5e2ff | 16 | #include "internal/sha3.h" |
91ce87c0 AP |
17 | #include "evp_locl.h" |
18 | ||
d5e5e2ff | 19 | static int init(EVP_MD_CTX *ctx) |
91ce87c0 | 20 | { |
d5e5e2ff | 21 | return sha3_init(EVP_MD_CTX_md_data(ctx), '\x06', ctx->digest->md_size * 8); |
91ce87c0 AP |
22 | } |
23 | ||
d5e5e2ff | 24 | static int update(EVP_MD_CTX *ctx, const void *_inp, size_t len) |
91ce87c0 | 25 | { |
d5e5e2ff | 26 | return sha3_update(EVP_MD_CTX_md_data(ctx), _inp, len); |
91ce87c0 AP |
27 | } |
28 | ||
d5e5e2ff | 29 | static int final(EVP_MD_CTX *ctx, unsigned char *md) |
91ce87c0 | 30 | { |
d5e5e2ff | 31 | return sha3_final(md, EVP_MD_CTX_md_data(ctx)); |
91ce87c0 AP |
32 | } |
33 | ||
d5e5e2ff | 34 | static int shake_init(EVP_MD_CTX *ctx) |
6e624a64 | 35 | { |
d5e5e2ff | 36 | return sha3_init(EVP_MD_CTX_md_data(ctx), '\x1f', ctx->digest->md_size * 8); |
91ce87c0 AP |
37 | } |
38 | ||
d5e5e2ff | 39 | static int kmac_init(EVP_MD_CTX *ctx) |
91ce87c0 | 40 | { |
d5e5e2ff SL |
41 | return keccak_kmac_init(EVP_MD_CTX_md_data(ctx), '\x04', |
42 | ctx->digest->md_size * 8 / 2); | |
91ce87c0 AP |
43 | } |
44 | ||
bbde4740 AP |
45 | static int shake_ctrl(EVP_MD_CTX *evp_ctx, int cmd, int p1, void *p2) |
46 | { | |
47 | KECCAK1600_CTX *ctx = evp_ctx->md_data; | |
48 | ||
49 | switch (cmd) { | |
50 | case EVP_MD_CTRL_XOF_LEN: | |
51 | ctx->md_size = p1; | |
52 | return 1; | |
53 | default: | |
54 | return 0; | |
55 | } | |
56 | } | |
57 | ||
f38edcab PS |
58 | #if defined(OPENSSL_CPUID_OBJ) && defined(__s390__) && defined(KECCAK1600_ASM) |
59 | /* | |
60 | * IBM S390X support | |
61 | */ | |
62 | # include "s390x_arch.h" | |
63 | ||
64 | # define S390X_SHA3_FC(ctx) ((ctx)->pad) | |
65 | ||
66 | # define S390X_sha3_224_CAPABLE ((OPENSSL_s390xcap_P.kimd[0] & \ | |
67 | S390X_CAPBIT(S390X_SHA3_224)) && \ | |
68 | (OPENSSL_s390xcap_P.klmd[0] & \ | |
69 | S390X_CAPBIT(S390X_SHA3_224))) | |
70 | # define S390X_sha3_256_CAPABLE ((OPENSSL_s390xcap_P.kimd[0] & \ | |
71 | S390X_CAPBIT(S390X_SHA3_256)) && \ | |
72 | (OPENSSL_s390xcap_P.klmd[0] & \ | |
73 | S390X_CAPBIT(S390X_SHA3_256))) | |
74 | # define S390X_sha3_384_CAPABLE ((OPENSSL_s390xcap_P.kimd[0] & \ | |
75 | S390X_CAPBIT(S390X_SHA3_384)) && \ | |
76 | (OPENSSL_s390xcap_P.klmd[0] & \ | |
77 | S390X_CAPBIT(S390X_SHA3_384))) | |
78 | # define S390X_sha3_512_CAPABLE ((OPENSSL_s390xcap_P.kimd[0] & \ | |
79 | S390X_CAPBIT(S390X_SHA3_512)) && \ | |
80 | (OPENSSL_s390xcap_P.klmd[0] & \ | |
81 | S390X_CAPBIT(S390X_SHA3_512))) | |
82 | # define S390X_shake128_CAPABLE ((OPENSSL_s390xcap_P.kimd[0] & \ | |
83 | S390X_CAPBIT(S390X_SHAKE_128)) && \ | |
84 | (OPENSSL_s390xcap_P.klmd[0] & \ | |
85 | S390X_CAPBIT(S390X_SHAKE_128))) | |
86 | # define S390X_shake256_CAPABLE ((OPENSSL_s390xcap_P.kimd[0] & \ | |
87 | S390X_CAPBIT(S390X_SHAKE_256)) && \ | |
88 | (OPENSSL_s390xcap_P.klmd[0] & \ | |
89 | S390X_CAPBIT(S390X_SHAKE_256))) | |
90 | ||
91 | /* Convert md-size to block-size. */ | |
92 | # define S390X_KECCAK1600_BSZ(n) ((KECCAK1600_WIDTH - ((n) << 1)) >> 3) | |
93 | ||
94 | static int s390x_sha3_init(EVP_MD_CTX *evp_ctx) | |
95 | { | |
96 | KECCAK1600_CTX *ctx = evp_ctx->md_data; | |
97 | const size_t bsz = evp_ctx->digest->block_size; | |
98 | ||
99 | /*- | |
100 | * KECCAK1600_CTX structure's pad field is used to store the KIMD/KLMD | |
101 | * function code. | |
102 | */ | |
103 | switch (bsz) { | |
104 | case S390X_KECCAK1600_BSZ(224): | |
105 | ctx->pad = S390X_SHA3_224; | |
106 | break; | |
107 | case S390X_KECCAK1600_BSZ(256): | |
108 | ctx->pad = S390X_SHA3_256; | |
109 | break; | |
110 | case S390X_KECCAK1600_BSZ(384): | |
111 | ctx->pad = S390X_SHA3_384; | |
112 | break; | |
113 | case S390X_KECCAK1600_BSZ(512): | |
114 | ctx->pad = S390X_SHA3_512; | |
115 | break; | |
116 | default: | |
117 | return 0; | |
118 | } | |
119 | ||
120 | memset(ctx->A, 0, sizeof(ctx->A)); | |
121 | ctx->num = 0; | |
122 | ctx->block_size = bsz; | |
123 | ctx->md_size = evp_ctx->digest->md_size; | |
124 | return 1; | |
125 | } | |
126 | ||
127 | static int s390x_shake_init(EVP_MD_CTX *evp_ctx) | |
128 | { | |
129 | KECCAK1600_CTX *ctx = evp_ctx->md_data; | |
130 | const size_t bsz = evp_ctx->digest->block_size; | |
131 | ||
132 | /*- | |
133 | * KECCAK1600_CTX structure's pad field is used to store the KIMD/KLMD | |
134 | * function code. | |
135 | */ | |
136 | switch (bsz) { | |
137 | case S390X_KECCAK1600_BSZ(128): | |
138 | ctx->pad = S390X_SHAKE_128; | |
139 | break; | |
140 | case S390X_KECCAK1600_BSZ(256): | |
141 | ctx->pad = S390X_SHAKE_256; | |
142 | break; | |
143 | default: | |
144 | return 0; | |
145 | } | |
146 | ||
147 | memset(ctx->A, 0, sizeof(ctx->A)); | |
148 | ctx->num = 0; | |
149 | ctx->block_size = bsz; | |
150 | ctx->md_size = evp_ctx->digest->md_size; | |
151 | return 1; | |
152 | } | |
153 | ||
154 | static int s390x_sha3_update(EVP_MD_CTX *evp_ctx, const void *_inp, size_t len) | |
155 | { | |
156 | KECCAK1600_CTX *ctx = evp_ctx->md_data; | |
157 | const unsigned char *inp = _inp; | |
158 | const size_t bsz = ctx->block_size; | |
159 | size_t num, rem; | |
160 | ||
161 | if (len == 0) | |
162 | return 1; | |
163 | ||
164 | if ((num = ctx->num) != 0) { | |
165 | rem = bsz - num; | |
166 | ||
167 | if (len < rem) { | |
168 | memcpy(ctx->buf + num, inp, len); | |
169 | ctx->num += len; | |
170 | return 1; | |
171 | } | |
172 | memcpy(ctx->buf + num, inp, rem); | |
173 | inp += rem; | |
174 | len -= rem; | |
175 | s390x_kimd(ctx->buf, bsz, ctx->pad, ctx->A); | |
176 | ctx->num = 0; | |
177 | } | |
178 | rem = len % bsz; | |
179 | ||
180 | s390x_kimd(inp, len - rem, ctx->pad, ctx->A); | |
181 | ||
182 | if (rem) { | |
183 | memcpy(ctx->buf, inp + len - rem, rem); | |
184 | ctx->num = rem; | |
185 | } | |
186 | return 1; | |
187 | } | |
188 | ||
189 | static int s390x_sha3_final(EVP_MD_CTX *evp_ctx, unsigned char *md) | |
190 | { | |
191 | KECCAK1600_CTX *ctx = evp_ctx->md_data; | |
192 | ||
193 | s390x_klmd(ctx->buf, ctx->num, NULL, 0, ctx->pad, ctx->A); | |
194 | memcpy(md, ctx->A, ctx->md_size); | |
195 | return 1; | |
196 | } | |
197 | ||
198 | static int s390x_shake_final(EVP_MD_CTX *evp_ctx, unsigned char *md) | |
199 | { | |
200 | KECCAK1600_CTX *ctx = evp_ctx->md_data; | |
201 | ||
202 | s390x_klmd(ctx->buf, ctx->num, md, ctx->md_size, ctx->pad, ctx->A); | |
203 | return 1; | |
204 | } | |
205 | ||
206 | # define EVP_MD_SHA3(bitlen) \ | |
207 | const EVP_MD *EVP_sha3_##bitlen(void) \ | |
208 | { \ | |
209 | static const EVP_MD s390x_sha3_##bitlen##_md = { \ | |
210 | NID_sha3_##bitlen, \ | |
211 | NID_RSA_SHA3_##bitlen, \ | |
212 | bitlen / 8, \ | |
213 | EVP_MD_FLAG_DIGALGID_ABSENT, \ | |
214 | s390x_sha3_init, \ | |
215 | s390x_sha3_update, \ | |
216 | s390x_sha3_final, \ | |
217 | NULL, \ | |
218 | NULL, \ | |
219 | (KECCAK1600_WIDTH - bitlen * 2) / 8, \ | |
220 | sizeof(KECCAK1600_CTX), \ | |
221 | }; \ | |
222 | static const EVP_MD sha3_##bitlen##_md = { \ | |
223 | NID_sha3_##bitlen, \ | |
224 | NID_RSA_SHA3_##bitlen, \ | |
225 | bitlen / 8, \ | |
226 | EVP_MD_FLAG_DIGALGID_ABSENT, \ | |
d5e5e2ff SL |
227 | init, \ |
228 | update, \ | |
229 | final, \ | |
f38edcab PS |
230 | NULL, \ |
231 | NULL, \ | |
232 | (KECCAK1600_WIDTH - bitlen * 2) / 8, \ | |
233 | sizeof(KECCAK1600_CTX), \ | |
234 | }; \ | |
235 | return S390X_sha3_##bitlen##_CAPABLE ? \ | |
236 | &s390x_sha3_##bitlen##_md : \ | |
237 | &sha3_##bitlen##_md; \ | |
238 | } | |
239 | ||
240 | # define EVP_MD_SHAKE(bitlen) \ | |
241 | const EVP_MD *EVP_shake##bitlen(void) \ | |
242 | { \ | |
243 | static const EVP_MD s390x_shake##bitlen##_md = { \ | |
244 | NID_shake##bitlen, \ | |
245 | 0, \ | |
246 | bitlen / 8, \ | |
247 | EVP_MD_FLAG_XOF, \ | |
248 | s390x_shake_init, \ | |
249 | s390x_sha3_update, \ | |
250 | s390x_shake_final, \ | |
251 | NULL, \ | |
252 | NULL, \ | |
253 | (KECCAK1600_WIDTH - bitlen * 2) / 8, \ | |
254 | sizeof(KECCAK1600_CTX), \ | |
255 | shake_ctrl \ | |
256 | }; \ | |
257 | static const EVP_MD shake##bitlen##_md = { \ | |
258 | NID_shake##bitlen, \ | |
259 | 0, \ | |
260 | bitlen / 8, \ | |
261 | EVP_MD_FLAG_XOF, \ | |
262 | shake_init, \ | |
d5e5e2ff SL |
263 | update, \ |
264 | final, \ | |
f38edcab PS |
265 | NULL, \ |
266 | NULL, \ | |
267 | (KECCAK1600_WIDTH - bitlen * 2) / 8, \ | |
268 | sizeof(KECCAK1600_CTX), \ | |
269 | shake_ctrl \ | |
270 | }; \ | |
271 | return S390X_shake##bitlen##_CAPABLE ? \ | |
272 | &s390x_shake##bitlen##_md : \ | |
273 | &shake##bitlen##_md; \ | |
274 | } | |
275 | ||
276 | #else | |
277 | ||
278 | # define EVP_MD_SHA3(bitlen) \ | |
91ce87c0 AP |
279 | const EVP_MD *EVP_sha3_##bitlen(void) \ |
280 | { \ | |
281 | static const EVP_MD sha3_##bitlen##_md = { \ | |
282 | NID_sha3_##bitlen, \ | |
c1ea7477 | 283 | NID_RSA_SHA3_##bitlen, \ |
91ce87c0 | 284 | bitlen / 8, \ |
c1ea7477 | 285 | EVP_MD_FLAG_DIGALGID_ABSENT, \ |
d5e5e2ff SL |
286 | init, \ |
287 | update, \ | |
288 | final, \ | |
91ce87c0 AP |
289 | NULL, \ |
290 | NULL, \ | |
291 | (KECCAK1600_WIDTH - bitlen * 2) / 8, \ | |
292 | sizeof(KECCAK1600_CTX), \ | |
293 | }; \ | |
294 | return &sha3_##bitlen##_md; \ | |
295 | } | |
296 | ||
f38edcab | 297 | # define EVP_MD_SHAKE(bitlen) \ |
91ce87c0 AP |
298 | const EVP_MD *EVP_shake##bitlen(void) \ |
299 | { \ | |
300 | static const EVP_MD shake##bitlen##_md = { \ | |
301 | NID_shake##bitlen, \ | |
302 | 0, \ | |
bbde4740 AP |
303 | bitlen / 8, \ |
304 | EVP_MD_FLAG_XOF, \ | |
91ce87c0 | 305 | shake_init, \ |
d5e5e2ff SL |
306 | update, \ |
307 | final, \ | |
91ce87c0 AP |
308 | NULL, \ |
309 | NULL, \ | |
310 | (KECCAK1600_WIDTH - bitlen * 2) / 8, \ | |
311 | sizeof(KECCAK1600_CTX), \ | |
bbde4740 | 312 | shake_ctrl \ |
91ce87c0 AP |
313 | }; \ |
314 | return &shake##bitlen##_md; \ | |
315 | } | |
6e624a64 | 316 | |
f38edcab PS |
317 | #endif |
318 | ||
319 | EVP_MD_SHA3(224) | |
320 | EVP_MD_SHA3(256) | |
321 | EVP_MD_SHA3(384) | |
322 | EVP_MD_SHA3(512) | |
91ce87c0 AP |
323 | |
324 | EVP_MD_SHAKE(128) | |
325 | EVP_MD_SHAKE(256) | |
6e624a64 SL |
326 | |
327 | ||
328 | # define EVP_MD_KECCAK_KMAC(bitlen) \ | |
329 | const EVP_MD *evp_keccak_kmac##bitlen(void) \ | |
330 | { \ | |
331 | static const EVP_MD kmac_##bitlen##_md = { \ | |
d5e5e2ff | 332 | NID_kmac##bitlen, \ |
6e624a64 SL |
333 | 0, \ |
334 | 2 * bitlen / 8, \ | |
335 | EVP_MD_FLAG_XOF, \ | |
336 | kmac_init, \ | |
d5e5e2ff SL |
337 | update, \ |
338 | final, \ | |
6e624a64 SL |
339 | NULL, \ |
340 | NULL, \ | |
341 | (KECCAK1600_WIDTH - bitlen * 2) / 8, \ | |
342 | sizeof(KECCAK1600_CTX), \ | |
343 | shake_ctrl \ | |
344 | }; \ | |
345 | return &kmac_##bitlen##_md; \ | |
346 | } | |
347 | ||
348 | EVP_MD_KECCAK_KMAC(128) | |
349 | EVP_MD_KECCAK_KMAC(256) |