Coverage Report

Created: 2025-06-22 06:56

/src/openssl/providers/implementations/digests/sha3_prov.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2019-2024 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
124
{
61
124
    if (!ossl_prov_is_running())
62
0
        return 0;
63
    /* The newctx() handles most of the ctx fixed setup. */
64
124
    ossl_sha3_reset((KECCAK1600_CTX *)vctx);
65
124
    return 1;
66
124
}
67
68
static int keccak_init_params(void *vctx, const OSSL_PARAM params[])
69
0
{
70
0
    return keccak_init(vctx, NULL)
71
0
            && shake_set_ctx_params(vctx, params);
72
0
}
73
74
static int keccak_update(void *vctx, const unsigned char *inp, size_t len)
75
124
{
76
124
    KECCAK1600_CTX *ctx = vctx;
77
124
    const size_t bsz = ctx->block_size;
78
124
    size_t num, rem;
79
80
124
    if (len == 0)
81
0
        return 1;
82
83
    /* Is there anything in the buffer already ? */
84
124
    if ((num = ctx->bufsz) != 0) {
85
        /* Calculate how much space is left in the buffer */
86
62
        rem = bsz - num;
87
        /* If the new input does not fill the buffer then just add it */
88
62
        if (len < rem) {
89
0
            memcpy(ctx->buf + num, inp, len);
90
0
            ctx->bufsz += len;
91
0
            return 1;
92
0
        }
93
        /* otherwise fill up the buffer and absorb the buffer */
94
62
        memcpy(ctx->buf + num, inp, rem);
95
        /* Update the input pointer */
96
62
        inp += rem;
97
62
        len -= rem;
98
62
        ctx->meth.absorb(ctx, ctx->buf, bsz);
99
62
        ctx->bufsz = 0;
100
62
    }
101
    /* Absorb the input - rem = leftover part of the input < blocksize) */
102
124
    rem = ctx->meth.absorb(ctx, inp, len);
103
    /* Copy the leftover bit of the input into the buffer */
104
124
    if (rem) {
105
121
        memcpy(ctx->buf, inp + len - rem, rem);
106
121
        ctx->bufsz = rem;
107
121
    }
108
124
    return 1;
109
124
}
110
111
static int keccak_final(void *vctx, unsigned char *out, size_t *outl,
112
                        size_t outlen)
113
62
{
114
62
    int ret = 1;
115
62
    KECCAK1600_CTX *ctx = vctx;
116
117
62
    if (!ossl_prov_is_running())
118
0
        return 0;
119
62
    if (ctx->md_size == SIZE_MAX) {
120
0
        ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_LENGTH);
121
0
        return 0;
122
0
    }
123
62
    if (outlen > 0)
124
62
        ret = ctx->meth.final(ctx, out, ctx->md_size);
125
126
62
    *outl = ctx->md_size;
127
62
    return ret;
128
62
}
129
130
static int shake_squeeze(void *vctx, unsigned char *out, size_t *outl,
131
                         size_t outlen)
132
0
{
133
0
    int ret = 1;
134
0
    KECCAK1600_CTX *ctx = vctx;
135
136
0
    if (!ossl_prov_is_running())
137
0
        return 0;
138
0
    if (ctx->meth.squeeze == NULL)
139
0
        return 0;
140
0
    if (outlen > 0)
141
0
        ret = ctx->meth.squeeze(ctx, out, outlen);
142
143
0
    *outl = outlen;
144
0
    return ret;
145
0
}
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
186
{
152
186
    KECCAK1600_CTX *ctx = vctx;
153
154
186
    if (!(ctx->xof_state == XOF_STATE_INIT ||
155
186
          ctx->xof_state == XOF_STATE_ABSORB))
156
0
        return 0;
157
186
    ctx->xof_state = XOF_STATE_ABSORB;
158
186
    return SHA3_absorb(ctx->A, inp, len, ctx->block_size);
159
186
}
160
161
static int generic_sha3_final(void *vctx, unsigned char *out, size_t outlen)
162
62
{
163
62
    return ossl_sha3_final((KECCAK1600_CTX *)vctx, out, outlen);
164
62
}
165
166
static int generic_sha3_squeeze(void *vctx, unsigned char *out, size_t outlen)
167
0
{
168
0
    return ossl_sha3_squeeze((KECCAK1600_CTX *)vctx, out, outlen);
169
0
}
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
62
# define SHA3_SET_MD(uname, typ) ctx->meth = sha3_generic_md;
482
0
# define KMAC_SET_MD(bitlen) ctx->meth = sha3_generic_md;
483
0
# 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
62
static void *name##_newctx(void *provctx)                                      \
489
62
{                                                                              \
490
62
    KECCAK1600_CTX *ctx = ossl_prov_is_running() ? OPENSSL_zalloc(sizeof(*ctx)) \
491
62
                                                : NULL;                        \
492
62
                                                                               \
493
62
    if (ctx == NULL)                                                           \
494
62
        return NULL;                                                           \
495
62
    ossl_sha3_init(ctx, pad, bitlen);                                          \
496
62
    SHA3_SET_MD(uname, typ)                                                    \
497
62
    return ctx;                                                                \
498
62
}
sha3_prov.c:sha3_224_newctx
Line
Count
Source
488
19
static void *name##_newctx(void *provctx)                                      \
489
19
{                                                                              \
490
19
    KECCAK1600_CTX *ctx = ossl_prov_is_running() ? OPENSSL_zalloc(sizeof(*ctx)) \
491
19
                                                : NULL;                        \
492
19
                                                                               \
493
19
    if (ctx == NULL)                                                           \
494
19
        return NULL;                                                           \
495
19
    ossl_sha3_init(ctx, pad, bitlen);                                          \
496
19
    SHA3_SET_MD(uname, typ)                                                    \
497
19
    return ctx;                                                                \
498
19
}
sha3_prov.c:sha3_256_newctx
Line
Count
Source
488
8
static void *name##_newctx(void *provctx)                                      \
489
8
{                                                                              \
490
8
    KECCAK1600_CTX *ctx = ossl_prov_is_running() ? OPENSSL_zalloc(sizeof(*ctx)) \
491
8
                                                : NULL;                        \
492
8
                                                                               \
493
8
    if (ctx == NULL)                                                           \
494
8
        return NULL;                                                           \
495
8
    ossl_sha3_init(ctx, pad, bitlen);                                          \
496
8
    SHA3_SET_MD(uname, typ)                                                    \
497
8
    return ctx;                                                                \
498
8
}
sha3_prov.c:sha3_384_newctx
Line
Count
Source
488
5
static void *name##_newctx(void *provctx)                                      \
489
5
{                                                                              \
490
5
    KECCAK1600_CTX *ctx = ossl_prov_is_running() ? OPENSSL_zalloc(sizeof(*ctx)) \
491
5
                                                : NULL;                        \
492
5
                                                                               \
493
5
    if (ctx == NULL)                                                           \
494
5
        return NULL;                                                           \
495
5
    ossl_sha3_init(ctx, pad, bitlen);                                          \
496
5
    SHA3_SET_MD(uname, typ)                                                    \
497
5
    return ctx;                                                                \
498
5
}
sha3_prov.c:sha3_512_newctx
Line
Count
Source
488
30
static void *name##_newctx(void *provctx)                                      \
489
30
{                                                                              \
490
30
    KECCAK1600_CTX *ctx = ossl_prov_is_running() ? OPENSSL_zalloc(sizeof(*ctx)) \
491
30
                                                : NULL;                        \
492
30
                                                                               \
493
30
    if (ctx == NULL)                                                           \
494
30
        return NULL;                                                           \
495
30
    ossl_sha3_init(ctx, pad, bitlen);                                          \
496
30
    SHA3_SET_MD(uname, typ)                                                    \
497
30
    return ctx;                                                                \
498
30
}
Unexecuted instantiation: sha3_prov.c:keccak_224_newctx
Unexecuted instantiation: sha3_prov.c:keccak_256_newctx
Unexecuted instantiation: sha3_prov.c:keccak_384_newctx
Unexecuted instantiation: sha3_prov.c:keccak_512_newctx
499
500
#define SHAKE_newctx(typ, uname, name, bitlen, mdlen, pad)                     \
501
static OSSL_FUNC_digest_newctx_fn name##_newctx;                               \
502
0
static void *name##_newctx(void *provctx)                                      \
503
0
{                                                                              \
504
0
    KECCAK1600_CTX *ctx = ossl_prov_is_running() ? OPENSSL_zalloc(sizeof(*ctx))\
505
0
                                                : NULL;                        \
506
0
                                                                               \
507
0
    if (ctx == NULL)                                                           \
508
0
        return NULL;                                                           \
509
0
    ossl_keccak_init(ctx, pad, bitlen, mdlen);                                 \
510
0
    if (mdlen == 0)                                                            \
511
0
        ctx->md_size = SIZE_MAX;                                               \
512
0
    SHAKE_SET_MD(uname, typ)                                                   \
513
0
    return ctx;                                                                \
514
0
}
Unexecuted instantiation: sha3_prov.c:shake_128_newctx
Unexecuted instantiation: sha3_prov.c:shake_256_newctx
515
516
#define KMAC_newctx(uname, bitlen, pad)                                        \
517
static OSSL_FUNC_digest_newctx_fn uname##_newctx;                              \
518
0
static void *uname##_newctx(void *provctx)                                     \
519
0
{                                                                              \
520
0
    KECCAK1600_CTX *ctx = ossl_prov_is_running() ? OPENSSL_zalloc(sizeof(*ctx)) \
521
0
                                                : NULL;                        \
522
0
                                                                               \
523
0
    if (ctx == NULL)                                                           \
524
0
        return NULL;                                                           \
525
0
    ossl_keccak_init(ctx, pad, bitlen, 2 * bitlen);                            \
526
0
    KMAC_SET_MD(bitlen)                                                        \
527
0
    return ctx;                                                                \
528
0
}
Unexecuted instantiation: sha3_prov.c:keccak_kmac_128_newctx
Unexecuted instantiation: sha3_prov.c:keccak_kmac_256_newctx
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
62
{
560
62
    KECCAK1600_CTX *ctx = (KECCAK1600_CTX *)vctx;
561
562
62
    OPENSSL_clear_free(ctx,  sizeof(*ctx));
563
62
}
564
565
static void keccak_copyctx(void *voutctx, void *vinctx)
566
0
{
567
0
    KECCAK1600_CTX *outctx = (KECCAK1600_CTX *)voutctx;
568
0
    KECCAK1600_CTX *inctx = (KECCAK1600_CTX *)vinctx;
569
570
0
    *outctx = *inctx;
571
0
}
572
573
static void *keccak_dupctx(void *ctx)
574
0
{
575
0
    KECCAK1600_CTX *in = (KECCAK1600_CTX *)ctx;
576
0
    KECCAK1600_CTX *ret = ossl_prov_is_running() ? OPENSSL_malloc(sizeof(*ret))
577
0
                                                 : NULL;
578
579
0
    if (ret != NULL)
580
0
        *ret = *in;
581
0
    return ret;
582
0
}
583
584
static const OSSL_PARAM *shake_gettable_ctx_params(ossl_unused void *ctx,
585
                                                   ossl_unused void *provctx)
586
0
{
587
0
    static const OSSL_PARAM known_shake_gettable_ctx_params[] = {
588
0
        {OSSL_DIGEST_PARAM_XOFLEN, OSSL_PARAM_UNSIGNED_INTEGER, NULL, 0, 0},
589
0
        {OSSL_DIGEST_PARAM_SIZE, OSSL_PARAM_UNSIGNED_INTEGER, NULL, 0, 0},
590
0
        OSSL_PARAM_END
591
0
    };
592
0
    return known_shake_gettable_ctx_params;
593
0
}
594
595
static int shake_get_ctx_params(void *vctx, OSSL_PARAM params[])
596
0
{
597
0
    OSSL_PARAM *p;
598
0
    KECCAK1600_CTX *ctx = (KECCAK1600_CTX *)vctx;
599
600
0
    if (ctx == NULL)
601
0
        return 0;
602
0
    if (ossl_param_is_empty(params))
603
0
        return 1;
604
605
0
    p = OSSL_PARAM_locate(params, OSSL_DIGEST_PARAM_XOFLEN);
606
0
    if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->md_size)) {
607
0
        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
608
0
        return 0;
609
0
    }
610
    /* Size is an alias of xoflen */
611
0
    p = OSSL_PARAM_locate(params, OSSL_DIGEST_PARAM_SIZE);
612
0
    if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->md_size)) {
613
0
        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
614
0
        return 0;
615
0
    }
616
0
    return 1;
617
0
}
618
619
static const OSSL_PARAM *shake_settable_ctx_params(ossl_unused void *ctx,
620
                                                   ossl_unused void *provctx)
621
0
{
622
0
    static const OSSL_PARAM known_shake_settable_ctx_params[] = {
623
0
        {OSSL_DIGEST_PARAM_XOFLEN, OSSL_PARAM_UNSIGNED_INTEGER, NULL, 0, 0},
624
0
        {OSSL_DIGEST_PARAM_SIZE, OSSL_PARAM_UNSIGNED_INTEGER, NULL, 0, 0},
625
0
        OSSL_PARAM_END
626
0
    };
627
628
0
    return known_shake_settable_ctx_params;
629
0
}
630
631
static int shake_set_ctx_params(void *vctx, const OSSL_PARAM params[])
632
0
{
633
0
    const OSSL_PARAM *p;
634
0
    KECCAK1600_CTX *ctx = (KECCAK1600_CTX *)vctx;
635
636
0
    if (ctx == NULL)
637
0
        return 0;
638
0
    if (ossl_param_is_empty(params))
639
0
        return 1;
640
641
0
    p = OSSL_PARAM_locate_const(params, OSSL_DIGEST_PARAM_XOFLEN);
642
0
    if (p == NULL)
643
0
        p = OSSL_PARAM_locate_const(params, OSSL_DIGEST_PARAM_SIZE);
644
645
0
    if (p != NULL && !OSSL_PARAM_get_size_t(p, &ctx->md_size)) {
646
0
        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
647
0
        return 0;
648
0
    }
649
0
    return 1;
650
0
}
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)