Coverage Report

Created: 2025-12-31 06:58

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