Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/openssl/providers/implementations/digests/sha3_prov.c
48383 views
1
/*
2
* Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.
3
*
4
* Licensed under the Apache License 2.0 (the "License"). You may not use
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 <string.h>
11
#include <openssl/core_names.h>
12
#include <openssl/crypto.h>
13
#include <openssl/evp.h>
14
#include <openssl/params.h>
15
#include <openssl/err.h>
16
#include <openssl/proverr.h>
17
#include "internal/numbers.h"
18
#include "internal/sha3.h"
19
#include "prov/digestcommon.h"
20
#include "prov/implementations.h"
21
22
#define SHA3_FLAGS PROV_DIGEST_FLAG_ALGID_ABSENT
23
#define SHAKE_FLAGS (PROV_DIGEST_FLAG_XOF | PROV_DIGEST_FLAG_ALGID_ABSENT)
24
#define KMAC_FLAGS PROV_DIGEST_FLAG_XOF
25
26
/*
27
* Forward declaration of any unique methods implemented here. This is not strictly
28
* necessary for the compiler, but provides an assurance that the signatures
29
* of the functions in the dispatch table are correct.
30
*/
31
static OSSL_FUNC_digest_init_fn keccak_init;
32
static OSSL_FUNC_digest_init_fn keccak_init_params;
33
static OSSL_FUNC_digest_update_fn keccak_update;
34
static OSSL_FUNC_digest_final_fn keccak_final;
35
static OSSL_FUNC_digest_freectx_fn keccak_freectx;
36
static OSSL_FUNC_digest_copyctx_fn keccak_copyctx;
37
static OSSL_FUNC_digest_dupctx_fn keccak_dupctx;
38
static OSSL_FUNC_digest_squeeze_fn shake_squeeze;
39
static OSSL_FUNC_digest_get_ctx_params_fn shake_get_ctx_params;
40
static OSSL_FUNC_digest_gettable_ctx_params_fn shake_gettable_ctx_params;
41
static OSSL_FUNC_digest_set_ctx_params_fn shake_set_ctx_params;
42
static OSSL_FUNC_digest_settable_ctx_params_fn shake_settable_ctx_params;
43
static sha3_absorb_fn generic_sha3_absorb;
44
static sha3_final_fn generic_sha3_final;
45
static sha3_squeeze_fn generic_sha3_squeeze;
46
47
#if defined(OPENSSL_CPUID_OBJ) && defined(__s390__) && defined(KECCAK1600_ASM)
48
/*
49
* IBM S390X support
50
*/
51
# include "s390x_arch.h"
52
# define S390_SHA3 1
53
# define S390_SHA3_CAPABLE(name) \
54
((OPENSSL_s390xcap_P.kimd[0] & S390X_CAPBIT(S390X_##name)) && \
55
(OPENSSL_s390xcap_P.klmd[0] & S390X_CAPBIT(S390X_##name)))
56
57
#endif
58
59
static int keccak_init(void *vctx, ossl_unused const OSSL_PARAM params[])
60
{
61
if (!ossl_prov_is_running())
62
return 0;
63
/* The newctx() handles most of the ctx fixed setup. */
64
ossl_sha3_reset((KECCAK1600_CTX *)vctx);
65
return 1;
66
}
67
68
static int keccak_init_params(void *vctx, const OSSL_PARAM params[])
69
{
70
return keccak_init(vctx, NULL)
71
&& shake_set_ctx_params(vctx, params);
72
}
73
74
static int keccak_update(void *vctx, const unsigned char *inp, size_t len)
75
{
76
KECCAK1600_CTX *ctx = vctx;
77
const size_t bsz = ctx->block_size;
78
size_t num, rem;
79
80
if (len == 0)
81
return 1;
82
83
/* Is there anything in the buffer already ? */
84
if ((num = ctx->bufsz) != 0) {
85
/* Calculate how much space is left in the buffer */
86
rem = bsz - num;
87
/* If the new input does not fill the buffer then just add it */
88
if (len < rem) {
89
memcpy(ctx->buf + num, inp, len);
90
ctx->bufsz += len;
91
return 1;
92
}
93
/* otherwise fill up the buffer and absorb the buffer */
94
memcpy(ctx->buf + num, inp, rem);
95
/* Update the input pointer */
96
inp += rem;
97
len -= rem;
98
ctx->meth.absorb(ctx, ctx->buf, bsz);
99
ctx->bufsz = 0;
100
}
101
/* Absorb the input - rem = leftover part of the input < blocksize) */
102
rem = ctx->meth.absorb(ctx, inp, len);
103
/* Copy the leftover bit of the input into the buffer */
104
if (rem) {
105
memcpy(ctx->buf, inp + len - rem, rem);
106
ctx->bufsz = rem;
107
}
108
return 1;
109
}
110
111
static int keccak_final(void *vctx, unsigned char *out, size_t *outl,
112
size_t outlen)
113
{
114
int ret = 1;
115
KECCAK1600_CTX *ctx = vctx;
116
117
if (!ossl_prov_is_running())
118
return 0;
119
if (ctx->md_size == SIZE_MAX) {
120
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_LENGTH);
121
return 0;
122
}
123
if (outlen > 0)
124
ret = ctx->meth.final(ctx, out, ctx->md_size);
125
126
*outl = ctx->md_size;
127
return ret;
128
}
129
130
static int shake_squeeze(void *vctx, unsigned char *out, size_t *outl,
131
size_t outlen)
132
{
133
int ret = 1;
134
KECCAK1600_CTX *ctx = vctx;
135
136
if (!ossl_prov_is_running())
137
return 0;
138
if (ctx->meth.squeeze == NULL)
139
return 0;
140
if (outlen > 0)
141
ret = ctx->meth.squeeze(ctx, out, outlen);
142
143
*outl = outlen;
144
return ret;
145
}
146
147
/*-
148
* Generic software version of the absorb() and final().
149
*/
150
static size_t generic_sha3_absorb(void *vctx, const void *inp, size_t len)
151
{
152
KECCAK1600_CTX *ctx = vctx;
153
154
if (!(ctx->xof_state == XOF_STATE_INIT ||
155
ctx->xof_state == XOF_STATE_ABSORB))
156
return 0;
157
ctx->xof_state = XOF_STATE_ABSORB;
158
return SHA3_absorb(ctx->A, inp, len, ctx->block_size);
159
}
160
161
static int generic_sha3_final(void *vctx, unsigned char *out, size_t outlen)
162
{
163
return ossl_sha3_final((KECCAK1600_CTX *)vctx, out, outlen);
164
}
165
166
static int generic_sha3_squeeze(void *vctx, unsigned char *out, size_t outlen)
167
{
168
return ossl_sha3_squeeze((KECCAK1600_CTX *)vctx, out, outlen);
169
}
170
171
static PROV_SHA3_METHOD sha3_generic_md = {
172
generic_sha3_absorb,
173
generic_sha3_final,
174
NULL
175
};
176
177
static PROV_SHA3_METHOD shake_generic_md =
178
{
179
generic_sha3_absorb,
180
generic_sha3_final,
181
generic_sha3_squeeze
182
};
183
184
#if defined(S390_SHA3)
185
186
static sha3_absorb_fn s390x_sha3_absorb;
187
static sha3_final_fn s390x_sha3_final;
188
static sha3_final_fn s390x_shake_final;
189
190
/*-
191
* The platform specific parts of the absorb() and final() for S390X.
192
*/
193
static size_t s390x_sha3_absorb(void *vctx, const void *inp, size_t len)
194
{
195
KECCAK1600_CTX *ctx = vctx;
196
size_t rem = len % ctx->block_size;
197
unsigned int fc;
198
199
if (!(ctx->xof_state == XOF_STATE_INIT ||
200
ctx->xof_state == XOF_STATE_ABSORB))
201
return 0;
202
if (len - rem > 0) {
203
fc = ctx->pad;
204
fc |= ctx->xof_state == XOF_STATE_INIT ? S390X_KIMD_NIP : 0;
205
ctx->xof_state = XOF_STATE_ABSORB;
206
s390x_kimd(inp, len - rem, fc, ctx->A);
207
}
208
return rem;
209
}
210
211
static int s390x_sha3_final(void *vctx, unsigned char *out, size_t outlen)
212
{
213
KECCAK1600_CTX *ctx = vctx;
214
unsigned int fc;
215
216
if (!ossl_prov_is_running())
217
return 0;
218
if (!(ctx->xof_state == XOF_STATE_INIT ||
219
ctx->xof_state == XOF_STATE_ABSORB))
220
return 0;
221
fc = ctx->pad | S390X_KLMD_DUFOP;
222
fc |= ctx->xof_state == XOF_STATE_INIT ? S390X_KLMD_NIP : 0;
223
ctx->xof_state = XOF_STATE_FINAL;
224
s390x_klmd(ctx->buf, ctx->bufsz, NULL, 0, fc, ctx->A);
225
memcpy(out, ctx->A, outlen);
226
return 1;
227
}
228
229
static int s390x_shake_final(void *vctx, unsigned char *out, size_t outlen)
230
{
231
KECCAK1600_CTX *ctx = vctx;
232
unsigned int fc;
233
234
if (!ossl_prov_is_running())
235
return 0;
236
if (!(ctx->xof_state == XOF_STATE_INIT ||
237
ctx->xof_state == XOF_STATE_ABSORB))
238
return 0;
239
fc = ctx->pad | S390X_KLMD_DUFOP;
240
fc |= ctx->xof_state == XOF_STATE_INIT ? S390X_KLMD_NIP : 0;
241
ctx->xof_state = XOF_STATE_FINAL;
242
s390x_klmd(ctx->buf, ctx->bufsz, out, outlen, fc, ctx->A);
243
return 1;
244
}
245
246
static int s390x_shake_squeeze(void *vctx, unsigned char *out, size_t outlen)
247
{
248
KECCAK1600_CTX *ctx = vctx;
249
unsigned int fc;
250
size_t len;
251
252
if (!ossl_prov_is_running())
253
return 0;
254
if (ctx->xof_state == XOF_STATE_FINAL)
255
return 0;
256
/*
257
* On the first squeeze call, finish the absorb process (incl. padding).
258
*/
259
if (ctx->xof_state != XOF_STATE_SQUEEZE) {
260
fc = ctx->pad;
261
fc |= ctx->xof_state == XOF_STATE_INIT ? S390X_KLMD_NIP : 0;
262
ctx->xof_state = XOF_STATE_SQUEEZE;
263
s390x_klmd(ctx->buf, ctx->bufsz, out, outlen, fc, ctx->A);
264
ctx->bufsz = outlen % ctx->block_size;
265
/* reuse ctx->bufsz to count bytes squeezed from current sponge */
266
return 1;
267
}
268
ctx->xof_state = XOF_STATE_SQUEEZE;
269
if (ctx->bufsz != 0) {
270
len = ctx->block_size - ctx->bufsz;
271
if (outlen < len)
272
len = outlen;
273
memcpy(out, (char *)ctx->A + ctx->bufsz, len);
274
out += len;
275
outlen -= len;
276
ctx->bufsz += len;
277
if (ctx->bufsz == ctx->block_size)
278
ctx->bufsz = 0;
279
}
280
if (outlen == 0)
281
return 1;
282
s390x_klmd(NULL, 0, out, outlen, ctx->pad | S390X_KLMD_PS, ctx->A);
283
ctx->bufsz = outlen % ctx->block_size;
284
285
return 1;
286
}
287
288
static int s390x_keccakc_final(void *vctx, unsigned char *out, size_t outlen,
289
int padding)
290
{
291
KECCAK1600_CTX *ctx = vctx;
292
size_t bsz = ctx->block_size;
293
size_t num = ctx->bufsz;
294
size_t needed = outlen;
295
unsigned int fc;
296
297
if (!ossl_prov_is_running())
298
return 0;
299
if (!(ctx->xof_state == XOF_STATE_INIT ||
300
ctx->xof_state == XOF_STATE_ABSORB))
301
return 0;
302
fc = ctx->pad;
303
fc |= ctx->xof_state == XOF_STATE_INIT ? S390X_KIMD_NIP : 0;
304
ctx->xof_state = XOF_STATE_FINAL;
305
if (outlen == 0)
306
return 1;
307
memset(ctx->buf + num, 0, bsz - num);
308
ctx->buf[num] = padding;
309
ctx->buf[bsz - 1] |= 0x80;
310
s390x_kimd(ctx->buf, bsz, fc, ctx->A);
311
num = needed > bsz ? bsz : needed;
312
memcpy(out, ctx->A, num);
313
needed -= num;
314
if (needed > 0)
315
s390x_klmd(NULL, 0, out + bsz, needed,
316
ctx->pad | S390X_KLMD_PS | S390X_KLMD_DUFOP, ctx->A);
317
318
return 1;
319
}
320
321
static int s390x_keccak_final(void *vctx, unsigned char *out, size_t outlen)
322
{
323
return s390x_keccakc_final(vctx, out, outlen, 0x01);
324
}
325
326
static int s390x_kmac_final(void *vctx, unsigned char *out, size_t outlen)
327
{
328
return s390x_keccakc_final(vctx, out, outlen, 0x04);
329
}
330
331
static int s390x_keccakc_squeeze(void *vctx, unsigned char *out, size_t outlen,
332
int padding)
333
{
334
KECCAK1600_CTX *ctx = vctx;
335
size_t len;
336
unsigned int fc;
337
338
if (!ossl_prov_is_running())
339
return 0;
340
if (ctx->xof_state == XOF_STATE_FINAL)
341
return 0;
342
/*
343
* On the first squeeze call, finish the absorb process
344
* by adding the trailing padding and then doing
345
* a final absorb.
346
*/
347
if (ctx->xof_state != XOF_STATE_SQUEEZE) {
348
len = ctx->block_size - ctx->bufsz;
349
memset(ctx->buf + ctx->bufsz, 0, len);
350
ctx->buf[ctx->bufsz] = padding;
351
ctx->buf[ctx->block_size - 1] |= 0x80;
352
fc = ctx->pad;
353
fc |= ctx->xof_state == XOF_STATE_INIT ? S390X_KIMD_NIP : 0;
354
s390x_kimd(ctx->buf, ctx->block_size, fc, ctx->A);
355
ctx->bufsz = 0;
356
/* reuse ctx->bufsz to count bytes squeezed from current sponge */
357
}
358
if (ctx->bufsz != 0 || ctx->xof_state != XOF_STATE_SQUEEZE) {
359
len = ctx->block_size - ctx->bufsz;
360
if (outlen < len)
361
len = outlen;
362
memcpy(out, (char *)ctx->A + ctx->bufsz, len);
363
out += len;
364
outlen -= len;
365
ctx->bufsz += len;
366
if (ctx->bufsz == ctx->block_size)
367
ctx->bufsz = 0;
368
}
369
ctx->xof_state = XOF_STATE_SQUEEZE;
370
if (outlen == 0)
371
return 1;
372
s390x_klmd(NULL, 0, out, outlen, ctx->pad | S390X_KLMD_PS, ctx->A);
373
ctx->bufsz = outlen % ctx->block_size;
374
375
return 1;
376
}
377
378
static int s390x_keccak_squeeze(void *vctx, unsigned char *out, size_t outlen)
379
{
380
return s390x_keccakc_squeeze(vctx, out, outlen, 0x01);
381
}
382
383
static int s390x_kmac_squeeze(void *vctx, unsigned char *out, size_t outlen)
384
{
385
return s390x_keccakc_squeeze(vctx, out, outlen, 0x04);
386
}
387
388
static PROV_SHA3_METHOD sha3_s390x_md = {
389
s390x_sha3_absorb,
390
s390x_sha3_final,
391
NULL,
392
};
393
394
static PROV_SHA3_METHOD keccak_s390x_md = {
395
s390x_sha3_absorb,
396
s390x_keccak_final,
397
s390x_keccak_squeeze,
398
};
399
400
static PROV_SHA3_METHOD shake_s390x_md = {
401
s390x_sha3_absorb,
402
s390x_shake_final,
403
s390x_shake_squeeze,
404
};
405
406
static PROV_SHA3_METHOD kmac_s390x_md = {
407
s390x_sha3_absorb,
408
s390x_kmac_final,
409
s390x_kmac_squeeze,
410
};
411
412
# define SHAKE_SET_MD(uname, typ) \
413
if (S390_SHA3_CAPABLE(uname)) { \
414
ctx->pad = S390X_##uname; \
415
ctx->meth = typ##_s390x_md; \
416
} else { \
417
ctx->meth = shake_generic_md; \
418
}
419
420
# define SHA3_SET_MD(uname, typ) \
421
if (S390_SHA3_CAPABLE(uname)) { \
422
ctx->pad = S390X_##uname; \
423
ctx->meth = typ##_s390x_md; \
424
} else { \
425
ctx->meth = sha3_generic_md; \
426
}
427
# define KMAC_SET_MD(bitlen) \
428
if (S390_SHA3_CAPABLE(SHAKE_##bitlen)) { \
429
ctx->pad = S390X_SHAKE_##bitlen; \
430
ctx->meth = kmac_s390x_md; \
431
} else { \
432
ctx->meth = sha3_generic_md; \
433
}
434
#elif defined(__aarch64__) && defined(KECCAK1600_ASM)
435
# include "arm_arch.h"
436
437
static sha3_absorb_fn armsha3_sha3_absorb;
438
439
size_t SHA3_absorb_cext(uint64_t A[5][5], const unsigned char *inp, size_t len,
440
size_t r);
441
/*-
442
* Hardware-assisted ARMv8.2 SHA3 extension version of the absorb()
443
*/
444
static size_t armsha3_sha3_absorb(void *vctx, const void *inp, size_t len)
445
{
446
KECCAK1600_CTX *ctx = vctx;
447
448
return SHA3_absorb_cext(ctx->A, inp, len, ctx->block_size);
449
}
450
451
static PROV_SHA3_METHOD sha3_ARMSHA3_md = {
452
armsha3_sha3_absorb,
453
generic_sha3_final
454
};
455
static PROV_SHA3_METHOD shake_ARMSHA3_md =
456
{
457
armsha3_sha3_absorb,
458
generic_sha3_final,
459
generic_sha3_squeeze
460
};
461
# define SHAKE_SET_MD(uname, typ) \
462
if (OPENSSL_armcap_P & ARMV8_HAVE_SHA3_AND_WORTH_USING) { \
463
ctx->meth = shake_ARMSHA3_md; \
464
} else { \
465
ctx->meth = shake_generic_md; \
466
}
467
468
# define SHA3_SET_MD(uname, typ) \
469
if (OPENSSL_armcap_P & ARMV8_HAVE_SHA3_AND_WORTH_USING) { \
470
ctx->meth = sha3_ARMSHA3_md; \
471
} else { \
472
ctx->meth = sha3_generic_md; \
473
}
474
# define KMAC_SET_MD(bitlen) \
475
if (OPENSSL_armcap_P & ARMV8_HAVE_SHA3_AND_WORTH_USING) { \
476
ctx->meth = sha3_ARMSHA3_md; \
477
} else { \
478
ctx->meth = sha3_generic_md; \
479
}
480
#else
481
# define SHA3_SET_MD(uname, typ) ctx->meth = sha3_generic_md;
482
# define KMAC_SET_MD(bitlen) ctx->meth = sha3_generic_md;
483
# define SHAKE_SET_MD(uname, typ) ctx->meth = shake_generic_md;
484
#endif /* S390_SHA3 */
485
486
#define SHA3_newctx(typ, uname, name, bitlen, pad) \
487
static OSSL_FUNC_digest_newctx_fn name##_newctx; \
488
static void *name##_newctx(void *provctx) \
489
{ \
490
KECCAK1600_CTX *ctx = ossl_prov_is_running() ? OPENSSL_zalloc(sizeof(*ctx)) \
491
: NULL; \
492
\
493
if (ctx == NULL) \
494
return NULL; \
495
ossl_sha3_init(ctx, pad, bitlen); \
496
SHA3_SET_MD(uname, typ) \
497
return ctx; \
498
}
499
500
#define SHAKE_newctx(typ, uname, name, bitlen, mdlen, pad) \
501
static OSSL_FUNC_digest_newctx_fn name##_newctx; \
502
static void *name##_newctx(void *provctx) \
503
{ \
504
KECCAK1600_CTX *ctx = ossl_prov_is_running() ? OPENSSL_zalloc(sizeof(*ctx))\
505
: NULL; \
506
\
507
if (ctx == NULL) \
508
return NULL; \
509
ossl_keccak_init(ctx, pad, bitlen, mdlen); \
510
if (mdlen == 0) \
511
ctx->md_size = SIZE_MAX; \
512
SHAKE_SET_MD(uname, typ) \
513
return ctx; \
514
}
515
516
#define KMAC_newctx(uname, bitlen, pad) \
517
static OSSL_FUNC_digest_newctx_fn uname##_newctx; \
518
static void *uname##_newctx(void *provctx) \
519
{ \
520
KECCAK1600_CTX *ctx = ossl_prov_is_running() ? OPENSSL_zalloc(sizeof(*ctx)) \
521
: NULL; \
522
\
523
if (ctx == NULL) \
524
return NULL; \
525
ossl_keccak_init(ctx, pad, bitlen, 2 * bitlen); \
526
KMAC_SET_MD(bitlen) \
527
return ctx; \
528
}
529
530
#define PROV_FUNC_SHA3_DIGEST_COMMON(name, bitlen, blksize, dgstsize, flags) \
531
PROV_FUNC_DIGEST_GET_PARAM(name, blksize, dgstsize, flags) \
532
const OSSL_DISPATCH ossl_##name##_functions[] = { \
533
{ OSSL_FUNC_DIGEST_NEWCTX, (void (*)(void))name##_newctx }, \
534
{ OSSL_FUNC_DIGEST_UPDATE, (void (*)(void))keccak_update }, \
535
{ OSSL_FUNC_DIGEST_FINAL, (void (*)(void))keccak_final }, \
536
{ OSSL_FUNC_DIGEST_FREECTX, (void (*)(void))keccak_freectx }, \
537
{ OSSL_FUNC_DIGEST_DUPCTX, (void (*)(void))keccak_dupctx }, \
538
{ OSSL_FUNC_DIGEST_COPYCTX, (void (*)(void))keccak_copyctx }, \
539
PROV_DISPATCH_FUNC_DIGEST_GET_PARAMS(name)
540
541
#define PROV_FUNC_SHA3_DIGEST(name, bitlen, blksize, dgstsize, flags) \
542
PROV_FUNC_SHA3_DIGEST_COMMON(name, bitlen, blksize, dgstsize, flags), \
543
{ OSSL_FUNC_DIGEST_INIT, (void (*)(void))keccak_init }, \
544
PROV_DISPATCH_FUNC_DIGEST_CONSTRUCT_END
545
546
#define PROV_FUNC_SHAKE_DIGEST(name, bitlen, blksize, dgstsize, flags) \
547
PROV_FUNC_SHA3_DIGEST_COMMON(name, bitlen, blksize, dgstsize, flags), \
548
{ OSSL_FUNC_DIGEST_SQUEEZE, (void (*)(void))shake_squeeze }, \
549
{ OSSL_FUNC_DIGEST_INIT, (void (*)(void))keccak_init_params }, \
550
{ OSSL_FUNC_DIGEST_SET_CTX_PARAMS, (void (*)(void))shake_set_ctx_params }, \
551
{ OSSL_FUNC_DIGEST_SETTABLE_CTX_PARAMS, \
552
(void (*)(void))shake_settable_ctx_params }, \
553
{ OSSL_FUNC_DIGEST_GET_CTX_PARAMS, (void (*)(void))shake_get_ctx_params }, \
554
{ OSSL_FUNC_DIGEST_GETTABLE_CTX_PARAMS, \
555
(void (*)(void))shake_gettable_ctx_params }, \
556
PROV_DISPATCH_FUNC_DIGEST_CONSTRUCT_END
557
558
static void keccak_freectx(void *vctx)
559
{
560
KECCAK1600_CTX *ctx = (KECCAK1600_CTX *)vctx;
561
562
OPENSSL_clear_free(ctx, sizeof(*ctx));
563
}
564
565
static void keccak_copyctx(void *voutctx, void *vinctx)
566
{
567
KECCAK1600_CTX *outctx = (KECCAK1600_CTX *)voutctx;
568
KECCAK1600_CTX *inctx = (KECCAK1600_CTX *)vinctx;
569
570
*outctx = *inctx;
571
}
572
573
static void *keccak_dupctx(void *ctx)
574
{
575
KECCAK1600_CTX *in = (KECCAK1600_CTX *)ctx;
576
KECCAK1600_CTX *ret = ossl_prov_is_running() ? OPENSSL_malloc(sizeof(*ret))
577
: NULL;
578
579
if (ret != NULL)
580
*ret = *in;
581
return ret;
582
}
583
584
static const OSSL_PARAM *shake_gettable_ctx_params(ossl_unused void *ctx,
585
ossl_unused void *provctx)
586
{
587
static const OSSL_PARAM known_shake_gettable_ctx_params[] = {
588
{OSSL_DIGEST_PARAM_XOFLEN, OSSL_PARAM_UNSIGNED_INTEGER, NULL, 0, 0},
589
{OSSL_DIGEST_PARAM_SIZE, OSSL_PARAM_UNSIGNED_INTEGER, NULL, 0, 0},
590
OSSL_PARAM_END
591
};
592
return known_shake_gettable_ctx_params;
593
}
594
595
static int shake_get_ctx_params(void *vctx, OSSL_PARAM params[])
596
{
597
OSSL_PARAM *p;
598
KECCAK1600_CTX *ctx = (KECCAK1600_CTX *)vctx;
599
600
if (ctx == NULL)
601
return 0;
602
if (ossl_param_is_empty(params))
603
return 1;
604
605
p = OSSL_PARAM_locate(params, OSSL_DIGEST_PARAM_XOFLEN);
606
if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->md_size)) {
607
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
608
return 0;
609
}
610
/* Size is an alias of xoflen */
611
p = OSSL_PARAM_locate(params, OSSL_DIGEST_PARAM_SIZE);
612
if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->md_size)) {
613
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
614
return 0;
615
}
616
return 1;
617
}
618
619
static const OSSL_PARAM *shake_settable_ctx_params(ossl_unused void *ctx,
620
ossl_unused void *provctx)
621
{
622
static const OSSL_PARAM known_shake_settable_ctx_params[] = {
623
{OSSL_DIGEST_PARAM_XOFLEN, OSSL_PARAM_UNSIGNED_INTEGER, NULL, 0, 0},
624
{OSSL_DIGEST_PARAM_SIZE, OSSL_PARAM_UNSIGNED_INTEGER, NULL, 0, 0},
625
OSSL_PARAM_END
626
};
627
628
return known_shake_settable_ctx_params;
629
}
630
631
static int shake_set_ctx_params(void *vctx, const OSSL_PARAM params[])
632
{
633
const OSSL_PARAM *p;
634
KECCAK1600_CTX *ctx = (KECCAK1600_CTX *)vctx;
635
636
if (ctx == NULL)
637
return 0;
638
if (ossl_param_is_empty(params))
639
return 1;
640
641
p = OSSL_PARAM_locate_const(params, OSSL_DIGEST_PARAM_XOFLEN);
642
if (p == NULL)
643
p = OSSL_PARAM_locate_const(params, OSSL_DIGEST_PARAM_SIZE);
644
645
if (p != NULL && !OSSL_PARAM_get_size_t(p, &ctx->md_size)) {
646
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
647
return 0;
648
}
649
return 1;
650
}
651
652
#define IMPLEMENT_SHA3_functions(bitlen) \
653
SHA3_newctx(sha3, SHA3_##bitlen, sha3_##bitlen, bitlen, '\x06') \
654
PROV_FUNC_SHA3_DIGEST(sha3_##bitlen, bitlen, \
655
SHA3_BLOCKSIZE(bitlen), SHA3_MDSIZE(bitlen), \
656
SHA3_FLAGS)
657
658
#define IMPLEMENT_KECCAK_functions(bitlen) \
659
SHA3_newctx(keccak, KECCAK_##bitlen, keccak_##bitlen, bitlen, '\x01') \
660
PROV_FUNC_SHA3_DIGEST(keccak_##bitlen, bitlen, \
661
SHA3_BLOCKSIZE(bitlen), SHA3_MDSIZE(bitlen), \
662
SHA3_FLAGS)
663
664
#define IMPLEMENT_SHAKE_functions(bitlen) \
665
SHAKE_newctx(shake, SHAKE_##bitlen, shake_##bitlen, bitlen, \
666
0 /* no default md length */, '\x1f') \
667
PROV_FUNC_SHAKE_DIGEST(shake_##bitlen, bitlen, \
668
SHA3_BLOCKSIZE(bitlen), 0, \
669
SHAKE_FLAGS)
670
671
#define IMPLEMENT_KMAC_functions(bitlen) \
672
KMAC_newctx(keccak_kmac_##bitlen, bitlen, '\x04') \
673
PROV_FUNC_SHAKE_DIGEST(keccak_kmac_##bitlen, bitlen, \
674
SHA3_BLOCKSIZE(bitlen), KMAC_MDSIZE(bitlen), \
675
KMAC_FLAGS)
676
677
/* ossl_sha3_224_functions */
678
IMPLEMENT_SHA3_functions(224)
679
/* ossl_sha3_256_functions */
680
IMPLEMENT_SHA3_functions(256)
681
/* ossl_sha3_384_functions */
682
IMPLEMENT_SHA3_functions(384)
683
/* ossl_sha3_512_functions */
684
IMPLEMENT_SHA3_functions(512)
685
/* ossl_keccak_224_functions */
686
IMPLEMENT_KECCAK_functions(224)
687
/* ossl_keccak_256_functions */
688
IMPLEMENT_KECCAK_functions(256)
689
/* ossl_keccak_384_functions */
690
IMPLEMENT_KECCAK_functions(384)
691
/* ossl_keccak_512_functions */
692
IMPLEMENT_KECCAK_functions(512)
693
/* ossl_shake_128_functions */
694
IMPLEMENT_SHAKE_functions(128)
695
/* ossl_shake_256_functions */
696
IMPLEMENT_SHAKE_functions(256)
697
/* ossl_keccak_kmac_128_functions */
698
IMPLEMENT_KMAC_functions(128)
699
/* ossl_keccak_kmac_256_functions */
700
IMPLEMENT_KMAC_functions(256)
701
702