]>
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" | |
16 | #include "evp_locl.h" | |
17 | ||
18 | size_t SHA3_absorb(uint64_t A[5][5], const unsigned char *inp, size_t len, | |
19 | size_t r); | |
20 | void SHA3_squeeze(uint64_t A[5][5], unsigned char *out, size_t len, size_t r); | |
21 | ||
22 | #define KECCAK1600_WIDTH 1600 | |
23 | ||
24 | typedef struct { | |
25 | uint64_t A[5][5]; | |
26 | size_t block_size; /* cached ctx->digest->block_size */ | |
27 | size_t md_size; /* output length, variable in XOF */ | |
28 | size_t num; /* used bytes in below buffer */ | |
29 | unsigned char buf[KECCAK1600_WIDTH / 8 - 32]; | |
30 | unsigned char pad; | |
31 | } KECCAK1600_CTX; | |
32 | ||
33 | static int init(EVP_MD_CTX *evp_ctx, unsigned char pad) | |
34 | { | |
35 | KECCAK1600_CTX *ctx = evp_ctx->md_data; | |
36 | size_t bsz = evp_ctx->digest->block_size; | |
37 | ||
38 | if (bsz <= sizeof(ctx->buf)) { | |
39 | memset(ctx->A, 0, sizeof(ctx->A)); | |
40 | ||
41 | ctx->num = 0; | |
42 | ctx->block_size = bsz; | |
43 | ctx->md_size = evp_ctx->digest->md_size; | |
44 | ctx->pad = pad; | |
45 | ||
46 | return 1; | |
47 | } | |
48 | ||
49 | return 0; | |
50 | } | |
51 | ||
52 | static int sha3_init(EVP_MD_CTX *evp_ctx) | |
53 | { | |
54 | return init(evp_ctx, '\x06'); | |
55 | } | |
56 | ||
57 | static int shake_init(EVP_MD_CTX *evp_ctx) | |
58 | { | |
59 | return init(evp_ctx, '\x1f'); | |
60 | } | |
61 | ||
6e624a64 SL |
62 | static int kmac_init(EVP_MD_CTX *evp_ctx) |
63 | { | |
64 | return init(evp_ctx, '\x04'); | |
65 | } | |
66 | ||
91ce87c0 AP |
67 | static int sha3_update(EVP_MD_CTX *evp_ctx, const void *_inp, size_t len) |
68 | { | |
69 | KECCAK1600_CTX *ctx = evp_ctx->md_data; | |
70 | const unsigned char *inp = _inp; | |
71 | size_t bsz = ctx->block_size; | |
72 | size_t num, rem; | |
73 | ||
28c5b7d4 DMSP |
74 | if (len == 0) |
75 | return 1; | |
76 | ||
91ce87c0 AP |
77 | if ((num = ctx->num) != 0) { /* process intermediate buffer? */ |
78 | rem = bsz - num; | |
79 | ||
80 | if (len < rem) { | |
81 | memcpy(ctx->buf + num, inp, len); | |
82 | ctx->num += len; | |
83 | return 1; | |
84 | } | |
85 | /* | |
86 | * We have enough data to fill or overflow the intermediate | |
87 | * buffer. So we append |rem| bytes and process the block, | |
88 | * leaving the rest for later processing... | |
89 | */ | |
90 | memcpy(ctx->buf + num, inp, rem); | |
91 | inp += rem, len -= rem; | |
92 | (void)SHA3_absorb(ctx->A, ctx->buf, bsz, bsz); | |
93 | ctx->num = 0; | |
94 | /* ctx->buf is processed, ctx->num is guaranteed to be zero */ | |
95 | } | |
96 | ||
97 | if (len >= bsz) | |
98 | rem = SHA3_absorb(ctx->A, inp, len, bsz); | |
99 | else | |
100 | rem = len; | |
101 | ||
102 | if (rem) { | |
103 | memcpy(ctx->buf, inp + len - rem, rem); | |
104 | ctx->num = rem; | |
105 | } | |
106 | ||
107 | return 1; | |
108 | } | |
109 | ||
110 | static int sha3_final(EVP_MD_CTX *evp_ctx, unsigned char *md) | |
111 | { | |
112 | KECCAK1600_CTX *ctx = evp_ctx->md_data; | |
113 | size_t bsz = ctx->block_size; | |
114 | size_t num = ctx->num; | |
115 | ||
116 | /* | |
117 | * Pad the data with 10*1. Note that |num| can be |bsz - 1| | |
118 | * in which case both byte operations below are performed on | |
119 | * same byte... | |
120 | */ | |
121 | memset(ctx->buf + num, 0, bsz - num); | |
122 | ctx->buf[num] = ctx->pad; | |
123 | ctx->buf[bsz - 1] |= 0x80; | |
124 | ||
125 | (void)SHA3_absorb(ctx->A, ctx->buf, bsz, bsz); | |
126 | ||
127 | SHA3_squeeze(ctx->A, md, ctx->md_size, bsz); | |
128 | ||
129 | return 1; | |
130 | } | |
131 | ||
bbde4740 AP |
132 | static int shake_ctrl(EVP_MD_CTX *evp_ctx, int cmd, int p1, void *p2) |
133 | { | |
134 | KECCAK1600_CTX *ctx = evp_ctx->md_data; | |
135 | ||
136 | switch (cmd) { | |
137 | case EVP_MD_CTRL_XOF_LEN: | |
138 | ctx->md_size = p1; | |
139 | return 1; | |
140 | default: | |
141 | return 0; | |
142 | } | |
143 | } | |
144 | ||
f38edcab PS |
145 | #if defined(OPENSSL_CPUID_OBJ) && defined(__s390__) && defined(KECCAK1600_ASM) |
146 | /* | |
147 | * IBM S390X support | |
148 | */ | |
149 | # include "s390x_arch.h" | |
150 | ||
151 | # define S390X_SHA3_FC(ctx) ((ctx)->pad) | |
152 | ||
153 | # define S390X_sha3_224_CAPABLE ((OPENSSL_s390xcap_P.kimd[0] & \ | |
154 | S390X_CAPBIT(S390X_SHA3_224)) && \ | |
155 | (OPENSSL_s390xcap_P.klmd[0] & \ | |
156 | S390X_CAPBIT(S390X_SHA3_224))) | |
157 | # define S390X_sha3_256_CAPABLE ((OPENSSL_s390xcap_P.kimd[0] & \ | |
158 | S390X_CAPBIT(S390X_SHA3_256)) && \ | |
159 | (OPENSSL_s390xcap_P.klmd[0] & \ | |
160 | S390X_CAPBIT(S390X_SHA3_256))) | |
161 | # define S390X_sha3_384_CAPABLE ((OPENSSL_s390xcap_P.kimd[0] & \ | |
162 | S390X_CAPBIT(S390X_SHA3_384)) && \ | |
163 | (OPENSSL_s390xcap_P.klmd[0] & \ | |
164 | S390X_CAPBIT(S390X_SHA3_384))) | |
165 | # define S390X_sha3_512_CAPABLE ((OPENSSL_s390xcap_P.kimd[0] & \ | |
166 | S390X_CAPBIT(S390X_SHA3_512)) && \ | |
167 | (OPENSSL_s390xcap_P.klmd[0] & \ | |
168 | S390X_CAPBIT(S390X_SHA3_512))) | |
169 | # define S390X_shake128_CAPABLE ((OPENSSL_s390xcap_P.kimd[0] & \ | |
170 | S390X_CAPBIT(S390X_SHAKE_128)) && \ | |
171 | (OPENSSL_s390xcap_P.klmd[0] & \ | |
172 | S390X_CAPBIT(S390X_SHAKE_128))) | |
173 | # define S390X_shake256_CAPABLE ((OPENSSL_s390xcap_P.kimd[0] & \ | |
174 | S390X_CAPBIT(S390X_SHAKE_256)) && \ | |
175 | (OPENSSL_s390xcap_P.klmd[0] & \ | |
176 | S390X_CAPBIT(S390X_SHAKE_256))) | |
177 | ||
178 | /* Convert md-size to block-size. */ | |
179 | # define S390X_KECCAK1600_BSZ(n) ((KECCAK1600_WIDTH - ((n) << 1)) >> 3) | |
180 | ||
181 | static int s390x_sha3_init(EVP_MD_CTX *evp_ctx) | |
182 | { | |
183 | KECCAK1600_CTX *ctx = evp_ctx->md_data; | |
184 | const size_t bsz = evp_ctx->digest->block_size; | |
185 | ||
186 | /*- | |
187 | * KECCAK1600_CTX structure's pad field is used to store the KIMD/KLMD | |
188 | * function code. | |
189 | */ | |
190 | switch (bsz) { | |
191 | case S390X_KECCAK1600_BSZ(224): | |
192 | ctx->pad = S390X_SHA3_224; | |
193 | break; | |
194 | case S390X_KECCAK1600_BSZ(256): | |
195 | ctx->pad = S390X_SHA3_256; | |
196 | break; | |
197 | case S390X_KECCAK1600_BSZ(384): | |
198 | ctx->pad = S390X_SHA3_384; | |
199 | break; | |
200 | case S390X_KECCAK1600_BSZ(512): | |
201 | ctx->pad = S390X_SHA3_512; | |
202 | break; | |
203 | default: | |
204 | return 0; | |
205 | } | |
206 | ||
207 | memset(ctx->A, 0, sizeof(ctx->A)); | |
208 | ctx->num = 0; | |
209 | ctx->block_size = bsz; | |
210 | ctx->md_size = evp_ctx->digest->md_size; | |
211 | return 1; | |
212 | } | |
213 | ||
214 | static int s390x_shake_init(EVP_MD_CTX *evp_ctx) | |
215 | { | |
216 | KECCAK1600_CTX *ctx = evp_ctx->md_data; | |
217 | const size_t bsz = evp_ctx->digest->block_size; | |
218 | ||
219 | /*- | |
220 | * KECCAK1600_CTX structure's pad field is used to store the KIMD/KLMD | |
221 | * function code. | |
222 | */ | |
223 | switch (bsz) { | |
224 | case S390X_KECCAK1600_BSZ(128): | |
225 | ctx->pad = S390X_SHAKE_128; | |
226 | break; | |
227 | case S390X_KECCAK1600_BSZ(256): | |
228 | ctx->pad = S390X_SHAKE_256; | |
229 | break; | |
230 | default: | |
231 | return 0; | |
232 | } | |
233 | ||
234 | memset(ctx->A, 0, sizeof(ctx->A)); | |
235 | ctx->num = 0; | |
236 | ctx->block_size = bsz; | |
237 | ctx->md_size = evp_ctx->digest->md_size; | |
238 | return 1; | |
239 | } | |
240 | ||
241 | static int s390x_sha3_update(EVP_MD_CTX *evp_ctx, const void *_inp, size_t len) | |
242 | { | |
243 | KECCAK1600_CTX *ctx = evp_ctx->md_data; | |
244 | const unsigned char *inp = _inp; | |
245 | const size_t bsz = ctx->block_size; | |
246 | size_t num, rem; | |
247 | ||
248 | if (len == 0) | |
249 | return 1; | |
250 | ||
251 | if ((num = ctx->num) != 0) { | |
252 | rem = bsz - num; | |
253 | ||
254 | if (len < rem) { | |
255 | memcpy(ctx->buf + num, inp, len); | |
256 | ctx->num += len; | |
257 | return 1; | |
258 | } | |
259 | memcpy(ctx->buf + num, inp, rem); | |
260 | inp += rem; | |
261 | len -= rem; | |
262 | s390x_kimd(ctx->buf, bsz, ctx->pad, ctx->A); | |
263 | ctx->num = 0; | |
264 | } | |
265 | rem = len % bsz; | |
266 | ||
267 | s390x_kimd(inp, len - rem, ctx->pad, ctx->A); | |
268 | ||
269 | if (rem) { | |
270 | memcpy(ctx->buf, inp + len - rem, rem); | |
271 | ctx->num = rem; | |
272 | } | |
273 | return 1; | |
274 | } | |
275 | ||
276 | static int s390x_sha3_final(EVP_MD_CTX *evp_ctx, unsigned char *md) | |
277 | { | |
278 | KECCAK1600_CTX *ctx = evp_ctx->md_data; | |
279 | ||
280 | s390x_klmd(ctx->buf, ctx->num, NULL, 0, ctx->pad, ctx->A); | |
281 | memcpy(md, ctx->A, ctx->md_size); | |
282 | return 1; | |
283 | } | |
284 | ||
285 | static int s390x_shake_final(EVP_MD_CTX *evp_ctx, unsigned char *md) | |
286 | { | |
287 | KECCAK1600_CTX *ctx = evp_ctx->md_data; | |
288 | ||
289 | s390x_klmd(ctx->buf, ctx->num, md, ctx->md_size, ctx->pad, ctx->A); | |
290 | return 1; | |
291 | } | |
292 | ||
293 | # define EVP_MD_SHA3(bitlen) \ | |
294 | const EVP_MD *EVP_sha3_##bitlen(void) \ | |
295 | { \ | |
296 | static const EVP_MD s390x_sha3_##bitlen##_md = { \ | |
297 | NID_sha3_##bitlen, \ | |
298 | NID_RSA_SHA3_##bitlen, \ | |
299 | bitlen / 8, \ | |
300 | EVP_MD_FLAG_DIGALGID_ABSENT, \ | |
301 | s390x_sha3_init, \ | |
302 | s390x_sha3_update, \ | |
303 | s390x_sha3_final, \ | |
304 | NULL, \ | |
305 | NULL, \ | |
306 | (KECCAK1600_WIDTH - bitlen * 2) / 8, \ | |
307 | sizeof(KECCAK1600_CTX), \ | |
308 | }; \ | |
309 | static const EVP_MD sha3_##bitlen##_md = { \ | |
310 | NID_sha3_##bitlen, \ | |
311 | NID_RSA_SHA3_##bitlen, \ | |
312 | bitlen / 8, \ | |
313 | EVP_MD_FLAG_DIGALGID_ABSENT, \ | |
314 | sha3_init, \ | |
315 | sha3_update, \ | |
316 | sha3_final, \ | |
317 | NULL, \ | |
318 | NULL, \ | |
319 | (KECCAK1600_WIDTH - bitlen * 2) / 8, \ | |
320 | sizeof(KECCAK1600_CTX), \ | |
321 | }; \ | |
322 | return S390X_sha3_##bitlen##_CAPABLE ? \ | |
323 | &s390x_sha3_##bitlen##_md : \ | |
324 | &sha3_##bitlen##_md; \ | |
325 | } | |
326 | ||
327 | # define EVP_MD_SHAKE(bitlen) \ | |
328 | const EVP_MD *EVP_shake##bitlen(void) \ | |
329 | { \ | |
330 | static const EVP_MD s390x_shake##bitlen##_md = { \ | |
331 | NID_shake##bitlen, \ | |
332 | 0, \ | |
333 | bitlen / 8, \ | |
334 | EVP_MD_FLAG_XOF, \ | |
335 | s390x_shake_init, \ | |
336 | s390x_sha3_update, \ | |
337 | s390x_shake_final, \ | |
338 | NULL, \ | |
339 | NULL, \ | |
340 | (KECCAK1600_WIDTH - bitlen * 2) / 8, \ | |
341 | sizeof(KECCAK1600_CTX), \ | |
342 | shake_ctrl \ | |
343 | }; \ | |
344 | static const EVP_MD shake##bitlen##_md = { \ | |
345 | NID_shake##bitlen, \ | |
346 | 0, \ | |
347 | bitlen / 8, \ | |
348 | EVP_MD_FLAG_XOF, \ | |
349 | shake_init, \ | |
350 | sha3_update, \ | |
351 | sha3_final, \ | |
352 | NULL, \ | |
353 | NULL, \ | |
354 | (KECCAK1600_WIDTH - bitlen * 2) / 8, \ | |
355 | sizeof(KECCAK1600_CTX), \ | |
356 | shake_ctrl \ | |
357 | }; \ | |
358 | return S390X_shake##bitlen##_CAPABLE ? \ | |
359 | &s390x_shake##bitlen##_md : \ | |
360 | &shake##bitlen##_md; \ | |
361 | } | |
362 | ||
363 | #else | |
364 | ||
365 | # define EVP_MD_SHA3(bitlen) \ | |
91ce87c0 AP |
366 | const EVP_MD *EVP_sha3_##bitlen(void) \ |
367 | { \ | |
368 | static const EVP_MD sha3_##bitlen##_md = { \ | |
369 | NID_sha3_##bitlen, \ | |
c1ea7477 | 370 | NID_RSA_SHA3_##bitlen, \ |
91ce87c0 | 371 | bitlen / 8, \ |
c1ea7477 | 372 | EVP_MD_FLAG_DIGALGID_ABSENT, \ |
91ce87c0 AP |
373 | sha3_init, \ |
374 | sha3_update, \ | |
375 | sha3_final, \ | |
376 | NULL, \ | |
377 | NULL, \ | |
378 | (KECCAK1600_WIDTH - bitlen * 2) / 8, \ | |
379 | sizeof(KECCAK1600_CTX), \ | |
380 | }; \ | |
381 | return &sha3_##bitlen##_md; \ | |
382 | } | |
383 | ||
f38edcab | 384 | # define EVP_MD_SHAKE(bitlen) \ |
91ce87c0 AP |
385 | const EVP_MD *EVP_shake##bitlen(void) \ |
386 | { \ | |
387 | static const EVP_MD shake##bitlen##_md = { \ | |
388 | NID_shake##bitlen, \ | |
389 | 0, \ | |
bbde4740 AP |
390 | bitlen / 8, \ |
391 | EVP_MD_FLAG_XOF, \ | |
91ce87c0 AP |
392 | shake_init, \ |
393 | sha3_update, \ | |
394 | sha3_final, \ | |
395 | NULL, \ | |
396 | NULL, \ | |
397 | (KECCAK1600_WIDTH - bitlen * 2) / 8, \ | |
398 | sizeof(KECCAK1600_CTX), \ | |
bbde4740 | 399 | shake_ctrl \ |
91ce87c0 AP |
400 | }; \ |
401 | return &shake##bitlen##_md; \ | |
402 | } | |
6e624a64 | 403 | |
f38edcab PS |
404 | #endif |
405 | ||
406 | EVP_MD_SHA3(224) | |
407 | EVP_MD_SHA3(256) | |
408 | EVP_MD_SHA3(384) | |
409 | EVP_MD_SHA3(512) | |
91ce87c0 AP |
410 | |
411 | EVP_MD_SHAKE(128) | |
412 | EVP_MD_SHAKE(256) | |
6e624a64 SL |
413 | |
414 | ||
415 | # define EVP_MD_KECCAK_KMAC(bitlen) \ | |
416 | const EVP_MD *evp_keccak_kmac##bitlen(void) \ | |
417 | { \ | |
418 | static const EVP_MD kmac_##bitlen##_md = { \ | |
419 | -1, \ | |
420 | 0, \ | |
421 | 2 * bitlen / 8, \ | |
422 | EVP_MD_FLAG_XOF, \ | |
423 | kmac_init, \ | |
424 | sha3_update, \ | |
425 | sha3_final, \ | |
426 | NULL, \ | |
427 | NULL, \ | |
428 | (KECCAK1600_WIDTH - bitlen * 2) / 8, \ | |
429 | sizeof(KECCAK1600_CTX), \ | |
430 | shake_ctrl \ | |
431 | }; \ | |
432 | return &kmac_##bitlen##_md; \ | |
433 | } | |
434 | ||
435 | EVP_MD_KECCAK_KMAC(128) | |
436 | EVP_MD_KECCAK_KMAC(256) |