Coverage Report

Created: 2026-02-22 06:11

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openssl/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/byteorder.h>
12
#include <openssl/core_names.h>
13
#include <openssl/crypto.h>
14
#include <openssl/evp.h>
15
#include <openssl/params.h>
16
#include <openssl/err.h>
17
#include <openssl/proverr.h>
18
#include "internal/cryptlib.h"
19
#include "internal/numbers.h"
20
#include "internal/sha3.h"
21
#include "prov/digestcommon.h"
22
#include "prov/implementations.h"
23
#include "internal/common.h"
24
#include "providers/implementations/digests/sha3_prov.inc"
25
26
#define SHA3_FLAGS PROV_DIGEST_FLAG_ALGID_ABSENT
27
#define SHAKE_FLAGS (PROV_DIGEST_FLAG_XOF | PROV_DIGEST_FLAG_ALGID_ABSENT)
28
#define CSHAKE_KECCAK_FLAGS PROV_DIGEST_FLAG_XOF
29
30
/*
31
 * FIPS 202 Section 5.1 Specifies a padding mode that is added to the last
32
 * block that consists of a 1 bit followed by padding zero bits and a trailing
33
 * 1 bit (where the bits are in LSB order)
34
 *
35
 * For a given input message special algorithm context bits are appended:
36
 * i.e.
37
 *   KECCAK[c] = (No tag is used)
38
 *   SHA3   = 01
39
 *   SHAKE  = 1111
40
 *   CSHAKE_KECCAK = 00 (See NIST SP800-185 3.3 : i.e. it has 2 trailing zero bits)
41
 * Note that KMAC and TupleHash use CSHAKE_KECCAK.
42
 * The OpenSSL implementation only allows input messages that are in bytes,
43
 * so the above concatenated bits will start on a byte boundary.
44
 * Following these bits will be a 1 bit then the padding zeros which gives
45
 *
46
 *   KECCAK[c] = 1000
47
 *   SHA3   = 0110
48
 *   SHAKE  = 11111000
49
 *   CSHAKE_KECCAK = 0010 (See NIST SP800-185 3.3 : i.e. KMAC uses cSHAKE with a fixed string)
50
 *
51
 *   Which gives the following padding values as bytes.
52
 */
53
#define KECCAK_PADDING 0x01
54
#define SHA3_PADDING 0x06
55
#define SHAKE_PADDING 0x1f
56
#define CSHAKE_KECCAK_PADDING 0x04
57
58
/*
59
 * Forward declaration of any unique methods implemented here. This is not strictly
60
 * necessary for the compiler, but provides an assurance that the signatures
61
 * of the functions in the dispatch table are correct.
62
 */
63
static OSSL_FUNC_digest_init_fn keccak_init;
64
static OSSL_FUNC_digest_init_fn keccak_init_params;
65
static OSSL_FUNC_digest_update_fn keccak_update;
66
static OSSL_FUNC_digest_final_fn keccak_final;
67
static OSSL_FUNC_digest_freectx_fn keccak_freectx;
68
static OSSL_FUNC_digest_copyctx_fn keccak_copyctx;
69
static OSSL_FUNC_digest_dupctx_fn keccak_dupctx;
70
static OSSL_FUNC_digest_squeeze_fn shake_squeeze;
71
static OSSL_FUNC_digest_get_ctx_params_fn shake_get_ctx_params;
72
static OSSL_FUNC_digest_gettable_ctx_params_fn shake_gettable_ctx_params;
73
static OSSL_FUNC_digest_set_ctx_params_fn shake_set_ctx_params;
74
static OSSL_FUNC_digest_settable_ctx_params_fn shake_settable_ctx_params;
75
static sha3_absorb_fn generic_sha3_absorb;
76
static sha3_final_fn generic_sha3_final;
77
static sha3_squeeze_fn generic_sha3_squeeze;
78
79
#if defined(OPENSSL_CPUID_OBJ) && defined(__s390__) && defined(KECCAK1600_ASM)
80
/*
81
 * IBM S390X support
82
 */
83
#include "s390x_arch.h"
84
#define S390_SHA3 1
85
#define S390_SHA3_CAPABLE(name) \
86
    ((OPENSSL_s390xcap_P.kimd[0] & S390X_CAPBIT(S390X_##name)) && (OPENSSL_s390xcap_P.klmd[0] & S390X_CAPBIT(S390X_##name)))
87
#endif
88
89
static int keccak_init(void *vctx, ossl_unused const OSSL_PARAM params[])
90
114
{
91
114
    if (ossl_unlikely(!ossl_prov_is_running()))
92
0
        return 0;
93
    /* The newctx() handles most of the ctx fixed setup. */
94
114
    ossl_sha3_reset((KECCAK1600_CTX *)vctx);
95
114
    return 1;
96
114
}
97
98
static int keccak_init_params(void *vctx, const OSSL_PARAM params[])
99
4
{
100
4
    return keccak_init(vctx, NULL)
101
4
        && shake_set_ctx_params(vctx, params);
102
4
}
103
104
static int keccak_update(void *vctx, const unsigned char *inp, size_t len)
105
118
{
106
118
    return ossl_sha3_absorb((KECCAK1600_CTX *)vctx, inp, len);
107
118
}
108
109
static int keccak_final(void *vctx, unsigned char *out, size_t *outl,
110
    size_t outlen)
111
59
{
112
59
    int ret = 1;
113
59
    KECCAK1600_CTX *ctx = vctx;
114
115
59
    if (ossl_unlikely(!ossl_prov_is_running()))
116
0
        return 0;
117
59
    if (ossl_unlikely(ctx->md_size == SIZE_MAX)) {
118
0
        ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_LENGTH);
119
0
        return 0;
120
0
    }
121
59
    if (ossl_likely(outlen > 0))
122
59
        ret = ctx->meth.final(ctx, out, ctx->md_size);
123
124
59
    *outl = ctx->md_size;
125
59
    return ret;
126
59
}
127
128
static int shake_squeeze(void *vctx, unsigned char *out, size_t *outl,
129
    size_t outlen)
130
0
{
131
0
    int ret = 1;
132
0
    KECCAK1600_CTX *ctx = vctx;
133
134
0
    if (!ossl_prov_is_running())
135
0
        return 0;
136
0
    if (ctx->meth.squeeze == NULL)
137
0
        return 0;
138
0
    if (outlen > 0)
139
0
        ret = ctx->meth.squeeze(ctx, out, outlen);
140
141
0
    *outl = outlen;
142
0
    return ret;
143
0
}
144
145
/*-
146
 * Generic software version of the absorb() and final().
147
 */
148
static size_t generic_sha3_absorb(void *vctx, const void *inp, size_t len)
149
177
{
150
177
    KECCAK1600_CTX *ctx = vctx;
151
152
177
    if (!(ctx->xof_state == XOF_STATE_INIT || ctx->xof_state == XOF_STATE_ABSORB))
153
0
        return 0;
154
177
    ctx->xof_state = XOF_STATE_ABSORB;
155
177
    return SHA3_absorb(ctx->A, inp, len, ctx->block_size);
156
177
}
157
158
static int generic_sha3_final(void *vctx, unsigned char *out, size_t outlen)
159
59
{
160
59
    return ossl_sha3_final((KECCAK1600_CTX *)vctx, out, outlen);
161
59
}
162
163
static int generic_sha3_squeeze(void *vctx, unsigned char *out, size_t outlen)
164
0
{
165
0
    return ossl_sha3_squeeze((KECCAK1600_CTX *)vctx, out, outlen);
166
0
}
167
168
static PROV_SHA3_METHOD sha3_generic_md = {
169
    generic_sha3_absorb,
170
    generic_sha3_final,
171
    NULL
172
};
173
174
static PROV_SHA3_METHOD shake_generic_md = {
175
    generic_sha3_absorb,
176
    generic_sha3_final,
177
    generic_sha3_squeeze
178
};
179
180
#if defined(S390_SHA3)
181
182
static sha3_absorb_fn s390x_sha3_absorb;
183
static sha3_final_fn s390x_sha3_final;
184
static sha3_final_fn s390x_shake_final;
185
186
/*-
187
 * The platform specific parts of the absorb() and final() for S390X.
188
 */
189
static size_t s390x_sha3_absorb(void *vctx, const void *inp, size_t len)
190
{
191
    KECCAK1600_CTX *ctx = vctx;
192
    size_t rem = len % ctx->block_size;
193
    unsigned int fc;
194
195
    if (!(ctx->xof_state == XOF_STATE_INIT || ctx->xof_state == XOF_STATE_ABSORB))
196
        return 0;
197
    if (len - rem > 0) {
198
        fc = ctx->pad;
199
        fc |= ctx->xof_state == XOF_STATE_INIT ? S390X_KIMD_NIP : 0;
200
        ctx->xof_state = XOF_STATE_ABSORB;
201
        s390x_kimd(inp, len - rem, fc, ctx->A);
202
    }
203
    return rem;
204
}
205
206
static int s390x_sha3_final(void *vctx, unsigned char *out, size_t outlen)
207
{
208
    KECCAK1600_CTX *ctx = vctx;
209
    unsigned int fc;
210
211
    if (!ossl_prov_is_running())
212
        return 0;
213
    if (!(ctx->xof_state == XOF_STATE_INIT || ctx->xof_state == XOF_STATE_ABSORB))
214
        return 0;
215
    fc = ctx->pad | S390X_KLMD_DUFOP;
216
    fc |= ctx->xof_state == XOF_STATE_INIT ? S390X_KLMD_NIP : 0;
217
    ctx->xof_state = XOF_STATE_FINAL;
218
    s390x_klmd(ctx->buf, ctx->bufsz, NULL, 0, fc, ctx->A);
219
    memcpy(out, ctx->A, outlen);
220
    return 1;
221
}
222
223
static int s390x_shake_final(void *vctx, unsigned char *out, size_t outlen)
224
{
225
    KECCAK1600_CTX *ctx = vctx;
226
    unsigned int fc;
227
228
    if (!ossl_prov_is_running())
229
        return 0;
230
    if (!(ctx->xof_state == XOF_STATE_INIT || ctx->xof_state == XOF_STATE_ABSORB))
231
        return 0;
232
    fc = ctx->pad | S390X_KLMD_DUFOP;
233
    fc |= ctx->xof_state == XOF_STATE_INIT ? S390X_KLMD_NIP : 0;
234
    ctx->xof_state = XOF_STATE_FINAL;
235
    s390x_klmd(ctx->buf, ctx->bufsz, out, outlen, fc, ctx->A);
236
    return 1;
237
}
238
239
static int s390x_shake_squeeze(void *vctx, unsigned char *out, size_t outlen)
240
{
241
    KECCAK1600_CTX *ctx = vctx;
242
    unsigned int fc;
243
    size_t len;
244
245
    if (!ossl_prov_is_running())
246
        return 0;
247
    if (ctx->xof_state == XOF_STATE_FINAL)
248
        return 0;
249
    /*
250
     * On the first squeeze call, finish the absorb process (incl. padding).
251
     */
252
    if (ctx->xof_state != XOF_STATE_SQUEEZE) {
253
        fc = ctx->pad;
254
        fc |= ctx->xof_state == XOF_STATE_INIT ? S390X_KLMD_NIP : 0;
255
        ctx->xof_state = XOF_STATE_SQUEEZE;
256
        s390x_klmd(ctx->buf, ctx->bufsz, out, outlen, fc, ctx->A);
257
        ctx->bufsz = outlen % ctx->block_size;
258
        /* reuse ctx->bufsz to count bytes squeezed from current sponge */
259
        return 1;
260
    }
261
    ctx->xof_state = XOF_STATE_SQUEEZE;
262
    if (ctx->bufsz != 0) {
263
        len = ctx->block_size - ctx->bufsz;
264
        if (outlen < len)
265
            len = outlen;
266
        memcpy(out, (char *)ctx->A + ctx->bufsz, len);
267
        out += len;
268
        outlen -= len;
269
        ctx->bufsz += len;
270
        if (ctx->bufsz == ctx->block_size)
271
            ctx->bufsz = 0;
272
    }
273
    if (outlen == 0)
274
        return 1;
275
    s390x_klmd(NULL, 0, out, outlen, ctx->pad | S390X_KLMD_PS, ctx->A);
276
    ctx->bufsz = outlen % ctx->block_size;
277
278
    return 1;
279
}
280
281
static int s390x_keccakc_final(void *vctx, unsigned char *out, size_t outlen,
282
    int padding)
283
{
284
    KECCAK1600_CTX *ctx = vctx;
285
    size_t bsz = ctx->block_size;
286
    size_t num = ctx->bufsz;
287
    size_t needed = outlen;
288
    unsigned int fc;
289
290
    if (!ossl_prov_is_running())
291
        return 0;
292
    if (!(ctx->xof_state == XOF_STATE_INIT || ctx->xof_state == XOF_STATE_ABSORB))
293
        return 0;
294
    fc = ctx->pad;
295
    fc |= ctx->xof_state == XOF_STATE_INIT ? S390X_KIMD_NIP : 0;
296
    ctx->xof_state = XOF_STATE_FINAL;
297
    if (outlen == 0)
298
        return 1;
299
    memset(ctx->buf + num, 0, bsz - num);
300
    ctx->buf[num] = padding;
301
    ctx->buf[bsz - 1] |= 0x80;
302
    s390x_kimd(ctx->buf, bsz, fc, ctx->A);
303
    num = needed > bsz ? bsz : needed;
304
    memcpy(out, ctx->A, num);
305
    needed -= num;
306
    if (needed > 0)
307
        s390x_klmd(NULL, 0, out + bsz, needed,
308
            ctx->pad | S390X_KLMD_PS | S390X_KLMD_DUFOP, ctx->A);
309
310
    return 1;
311
}
312
313
static int s390x_keccak_final(void *vctx, unsigned char *out, size_t outlen)
314
{
315
    return s390x_keccakc_final(vctx, out, outlen, 0x01);
316
}
317
318
static int s390x_cshake_keccak_final(void *vctx, unsigned char *out, size_t outlen)
319
{
320
    return s390x_keccakc_final(vctx, out, outlen, 0x04);
321
}
322
323
static int s390x_keccakc_squeeze(void *vctx, unsigned char *out, size_t outlen,
324
    int padding)
325
{
326
    KECCAK1600_CTX *ctx = vctx;
327
    size_t len;
328
    unsigned int fc;
329
330
    if (!ossl_prov_is_running())
331
        return 0;
332
    if (ctx->xof_state == XOF_STATE_FINAL)
333
        return 0;
334
    /*
335
     * On the first squeeze call, finish the absorb process
336
     * by adding the trailing padding and then doing
337
     * a final absorb.
338
     */
339
    if (ctx->xof_state != XOF_STATE_SQUEEZE) {
340
        len = ctx->block_size - ctx->bufsz;
341
        memset(ctx->buf + ctx->bufsz, 0, len);
342
        ctx->buf[ctx->bufsz] = padding;
343
        ctx->buf[ctx->block_size - 1] |= 0x80;
344
        fc = ctx->pad;
345
        fc |= ctx->xof_state == XOF_STATE_INIT ? S390X_KIMD_NIP : 0;
346
        s390x_kimd(ctx->buf, ctx->block_size, fc, ctx->A);
347
        ctx->bufsz = 0;
348
        /* reuse ctx->bufsz to count bytes squeezed from current sponge */
349
    }
350
    if (ctx->bufsz != 0 || ctx->xof_state != XOF_STATE_SQUEEZE) {
351
        len = ctx->block_size - ctx->bufsz;
352
        if (outlen < len)
353
            len = outlen;
354
        memcpy(out, (char *)ctx->A + ctx->bufsz, len);
355
        out += len;
356
        outlen -= len;
357
        ctx->bufsz += len;
358
        if (ctx->bufsz == ctx->block_size)
359
            ctx->bufsz = 0;
360
    }
361
    ctx->xof_state = XOF_STATE_SQUEEZE;
362
    if (outlen == 0)
363
        return 1;
364
    s390x_klmd(NULL, 0, out, outlen, ctx->pad | S390X_KLMD_PS, ctx->A);
365
    ctx->bufsz = outlen % ctx->block_size;
366
367
    return 1;
368
}
369
370
static int s390x_keccak_squeeze(void *vctx, unsigned char *out, size_t outlen)
371
{
372
    return s390x_keccakc_squeeze(vctx, out, outlen, KECCAK_PADDING);
373
}
374
375
static int s390x_cshake_keccak_squeeze(void *vctx, unsigned char *out, size_t outlen)
376
{
377
    return s390x_keccakc_squeeze(vctx, out, outlen, CSHAKE_KECCAK_PADDING);
378
}
379
380
static PROV_SHA3_METHOD sha3_s390x_md = {
381
    s390x_sha3_absorb,
382
    s390x_sha3_final,
383
    NULL,
384
};
385
386
static PROV_SHA3_METHOD keccak_s390x_md = {
387
    s390x_sha3_absorb,
388
    s390x_keccak_final,
389
    s390x_keccak_squeeze,
390
};
391
392
static PROV_SHA3_METHOD shake_s390x_md = {
393
    s390x_sha3_absorb,
394
    s390x_shake_final,
395
    s390x_shake_squeeze,
396
};
397
398
static PROV_SHA3_METHOD cshake_keccak_s390x_md = {
399
    s390x_sha3_absorb,
400
    s390x_cshake_keccak_final,
401
    s390x_cshake_keccak_squeeze,
402
};
403
404
#define SHAKE_SET_MD(uname, typ)      \
405
    if (S390_SHA3_CAPABLE(uname)) {   \
406
        ctx->pad = S390X_##uname;     \
407
        ctx->meth = typ##_s390x_md;   \
408
    } else {                          \
409
        ctx->meth = shake_generic_md; \
410
    }
411
412
#define SHA3_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 = sha3_generic_md; \
418
    }
419
#define CSHAKE_KECCAK_SET_MD(bitlen)         \
420
    if (S390_SHA3_CAPABLE(SHAKE_##bitlen)) { \
421
        ctx->pad = S390X_SHAKE_##bitlen;     \
422
        ctx->meth = cshake_keccak_s390x_md;  \
423
    } else {                                 \
424
        ctx->meth = shake_generic_md;        \
425
    }
426
#elif defined(__aarch64__) && defined(KECCAK1600_ASM)
427
#include "arm_arch.h"
428
429
static sha3_absorb_fn armsha3_sha3_absorb;
430
431
size_t SHA3_absorb_cext(uint64_t A[5][5], const unsigned char *inp, size_t len,
432
    size_t r);
433
/*-
434
 * Hardware-assisted ARMv8.2 SHA3 extension version of the absorb()
435
 */
436
static size_t armsha3_sha3_absorb(void *vctx, const void *inp, size_t len)
437
{
438
    KECCAK1600_CTX *ctx = vctx;
439
440
    return SHA3_absorb_cext(ctx->A, inp, len, ctx->block_size);
441
}
442
443
static PROV_SHA3_METHOD sha3_ARMSHA3_md = {
444
    armsha3_sha3_absorb,
445
    generic_sha3_final
446
};
447
static PROV_SHA3_METHOD shake_ARMSHA3_md = {
448
    armsha3_sha3_absorb,
449
    generic_sha3_final,
450
    generic_sha3_squeeze
451
};
452
#define SHAKE_SET_MD(uname, typ)                              \
453
    if (OPENSSL_armcap_P & ARMV8_HAVE_SHA3_AND_WORTH_USING) { \
454
        ctx->meth = shake_ARMSHA3_md;                         \
455
    } else {                                                  \
456
        ctx->meth = shake_generic_md;                         \
457
    }
458
459
#define SHA3_SET_MD(uname, typ)                               \
460
    if (OPENSSL_armcap_P & ARMV8_HAVE_SHA3_AND_WORTH_USING) { \
461
        ctx->meth = sha3_ARMSHA3_md;                          \
462
    } else {                                                  \
463
        ctx->meth = sha3_generic_md;                          \
464
    }
465
#define CSHAKE_KECCAK_SET_MD(bitlen)                          \
466
    if (OPENSSL_armcap_P & ARMV8_HAVE_SHA3_AND_WORTH_USING) { \
467
        ctx->meth = shake_ARMSHA3_md;                         \
468
    } else {                                                  \
469
        ctx->meth = shake_generic_md;                         \
470
    }
471
#else
472
55
#define SHA3_SET_MD(uname, typ) ctx->meth = sha3_generic_md;
473
0
#define CSHAKE_KECCAK_SET_MD(bitlen) ctx->meth = shake_generic_md;
474
4
#define SHAKE_SET_MD(uname, typ) ctx->meth = shake_generic_md;
475
#endif /* S390_SHA3 */
476
477
#define SHA3_newctx(typ, uname, name, bitlen, pad)        \
478
    static OSSL_FUNC_digest_newctx_fn name##_newctx;      \
479
    static void *name##_newctx(void *provctx)             \
480
55
    {                                                     \
481
55
        KECCAK1600_CTX *ctx;                              \
482
55
                                                          \
483
55
        DIGEST_PROV_CHECK(provctx, SHA3_256);             \
484
55
        if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) \
485
55
            return NULL;                                  \
486
55
        ossl_sha3_init(ctx, pad, bitlen);                 \
487
55
        SHA3_SET_MD(uname, typ)                           \
488
55
        return ctx;                                       \
489
55
    }
490
491
#define SHAKE_newctx(typ, uname, name, bitlen, mdlen, pad) \
492
    static OSSL_FUNC_digest_newctx_fn name##_newctx;       \
493
    static void *name##_newctx(void *provctx)              \
494
4
    {                                                      \
495
4
        KECCAK1600_CTX *ctx;                               \
496
4
                                                           \
497
4
        DIGEST_PROV_CHECK(provctx, SHA3_256);              \
498
4
        if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL)  \
499
4
            return NULL;                                   \
500
4
        ossl_keccak_init(ctx, pad, bitlen, mdlen);         \
501
4
        if (mdlen == 0)                                    \
502
4
            ctx->md_size = SIZE_MAX;                       \
503
4
        SHAKE_SET_MD(uname, typ)                           \
504
4
        return ctx;                                        \
505
4
    }
506
507
#define CSHAKE_KECCAK_newctx(uname, bitlen, pad)          \
508
    static OSSL_FUNC_digest_newctx_fn uname##_newctx;     \
509
    static void *uname##_newctx(void *provctx)            \
510
0
    {                                                     \
511
0
        KECCAK1600_CTX *ctx;                              \
512
0
                                                          \
513
0
        DIGEST_PROV_CHECK(provctx, SHA3_256);             \
514
0
        if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) \
515
0
            return NULL;                                  \
516
0
        ossl_keccak_init(ctx, pad, bitlen, 2 * bitlen);   \
517
0
        CSHAKE_KECCAK_SET_MD(bitlen)                      \
518
0
        return ctx;                                       \
519
0
    }
520
521
#define KMAC_newctx(uname, bitlen, pad)                   \
522
    static OSSL_FUNC_digest_newctx_fn uname##_newctx;     \
523
    static void *uname##_newctx(void *provctx)            \
524
    {                                                     \
525
        KECCAK1600_CTX *ctx;                              \
526
                                                          \
527
        DIGEST_PROV_CHECK(provctx, SHA3_256);             \
528
        if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) \
529
            return NULL;                                  \
530
        ossl_keccak_init(ctx, pad, bitlen, 2 * bitlen);   \
531
        KMAC_SET_MD(bitlen)                               \
532
        return ctx;                                       \
533
    }
534
535
#define PROV_FUNC_SHA3_DIGEST_COMMON(name, bitlen, blksize, dgstsize, flags)  \
536
    PROV_FUNC_DIGEST_GET_PARAM(name, blksize, dgstsize, flags)                \
537
    const OSSL_DISPATCH ossl_##name##_functions[] = {                         \
538
        { OSSL_FUNC_DIGEST_NEWCTX, (void (*)(void))name##_newctx },           \
539
        { OSSL_FUNC_DIGEST_UPDATE, (void (*)(void))keccak_update },           \
540
        { OSSL_FUNC_DIGEST_FINAL, (void (*)(void))keccak_final },             \
541
        { OSSL_FUNC_DIGEST_FREECTX, (void (*)(void))keccak_freectx },         \
542
        { OSSL_FUNC_DIGEST_DUPCTX, (void (*)(void))keccak_dupctx },           \
543
        { OSSL_FUNC_DIGEST_COPYCTX, (void (*)(void))keccak_copyctx },         \
544
        { OSSL_FUNC_DIGEST_SERIALIZE, (void (*)(void))name##_serialize },     \
545
        { OSSL_FUNC_DIGEST_DESERIALIZE, (void (*)(void))name##_deserialize }, \
546
        PROV_DISPATCH_FUNC_DIGEST_GET_PARAMS(name)
547
548
#define PROV_FUNC_SHA3_DIGEST(name, bitlen, blksize, dgstsize, flags)     \
549
    PROV_FUNC_SHA3_DIGEST_COMMON(name, bitlen, blksize, dgstsize, flags), \
550
        { OSSL_FUNC_DIGEST_INIT, (void (*)(void))keccak_init },           \
551
        PROV_DISPATCH_FUNC_DIGEST_CONSTRUCT_END
552
553
#define PROV_FUNC_SHAKE_DIGEST(name, bitlen, blksize, dgstsize, flags)             \
554
    PROV_FUNC_SHA3_DIGEST_COMMON(name, bitlen, blksize, dgstsize, flags),          \
555
        { OSSL_FUNC_DIGEST_SQUEEZE, (void (*)(void))shake_squeeze },               \
556
        { OSSL_FUNC_DIGEST_INIT, (void (*)(void))keccak_init_params },             \
557
        { OSSL_FUNC_DIGEST_SET_CTX_PARAMS, (void (*)(void))shake_set_ctx_params }, \
558
        { OSSL_FUNC_DIGEST_SETTABLE_CTX_PARAMS,                                    \
559
            (void (*)(void))shake_settable_ctx_params },                           \
560
        { OSSL_FUNC_DIGEST_GET_CTX_PARAMS, (void (*)(void))shake_get_ctx_params }, \
561
        { OSSL_FUNC_DIGEST_GETTABLE_CTX_PARAMS,                                    \
562
            (void (*)(void))shake_gettable_ctx_params },                           \
563
        PROV_DISPATCH_FUNC_DIGEST_CONSTRUCT_END
564
565
static void keccak_freectx(void *vctx)
566
59
{
567
59
    KECCAK1600_CTX *ctx = (KECCAK1600_CTX *)vctx;
568
569
59
    OPENSSL_clear_free(ctx, sizeof(*ctx));
570
59
}
571
572
static void keccak_copyctx(void *voutctx, void *vinctx)
573
0
{
574
0
    KECCAK1600_CTX *outctx = (KECCAK1600_CTX *)voutctx;
575
0
    KECCAK1600_CTX *inctx = (KECCAK1600_CTX *)vinctx;
576
577
0
    *outctx = *inctx;
578
0
}
579
580
static void *keccak_dupctx(void *ctx)
581
0
{
582
0
    KECCAK1600_CTX *in = (KECCAK1600_CTX *)ctx;
583
0
    KECCAK1600_CTX *ret = ossl_prov_is_running() ? OPENSSL_malloc(sizeof(*ret))
584
0
                                                 : NULL;
585
586
0
    if (ret != NULL)
587
0
        *ret = *in;
588
0
    return ret;
589
0
}
590
591
static const unsigned char keccakmagic[] = "KECCAKv1";
592
0
#define KECCAKMAGIC_LEN (sizeof(keccakmagic) - 1)
593
#define KECCAK_SERIALIZATION_LEN                                                     \
594
0
    (                                                                                \
595
0
        KECCAKMAGIC_LEN /* magic string */                                           \
596
0
        + sizeof(uint64_t) /* impl-ID */                                             \
597
0
        + sizeof(uint64_t) /* c->md_size */                                          \
598
0
        + (sizeof(uint64_t) * 4) /* c->block_size, c->bufsz, c->pad, c->xof_state */ \
599
0
        + (sizeof(uint64_t) * 5 * 5) /* c->A */                                      \
600
0
        + (KECCAK1600_WIDTH / 8 - 32) /* c->buf */                                   \
601
0
    )
602
603
static int KECCAK_Serialize(KECCAK1600_CTX *c, int impl_id,
604
    unsigned char *output, size_t *outlen)
605
0
{
606
0
    unsigned char *p;
607
0
    int i, j;
608
609
0
    if (output == NULL) {
610
0
        if (outlen == NULL)
611
0
            return 0;
612
613
0
        *outlen = KECCAK_SERIALIZATION_LEN;
614
0
        return 1;
615
0
    }
616
617
0
    if (outlen != NULL && *outlen < KECCAK_SERIALIZATION_LEN)
618
0
        return 0;
619
620
0
    p = output;
621
622
    /* Magic code */
623
0
    memcpy(p, keccakmagic, KECCAKMAGIC_LEN);
624
0
    p += KECCAKMAGIC_LEN;
625
626
    /* Additional check data */
627
0
    p = OPENSSL_store_u64_le(p, impl_id);
628
0
    p = OPENSSL_store_u64_le(p, c->md_size);
629
630
0
    p = OPENSSL_store_u64_le(p, c->block_size);
631
0
    p = OPENSSL_store_u64_le(p, c->bufsz);
632
0
    p = OPENSSL_store_u64_le(p, c->pad);
633
0
    p = OPENSSL_store_u64_le(p, c->xof_state);
634
635
    /* A matrix */
636
0
    for (i = 0; i < 5; i++) {
637
0
        for (j = 0; j < 5; j++)
638
0
            p = OPENSSL_store_u64_le(p, c->A[i][j]);
639
0
    }
640
641
0
    if (outlen != NULL)
642
0
        *outlen = KECCAK_SERIALIZATION_LEN;
643
644
    /* buf */
645
0
    memcpy(p, c->buf, sizeof(c->buf));
646
647
0
    return 1;
648
0
}
649
650
/*
651
 * This function only performs basic input sanity checks and is not
652
 * built to handle malicious input data. Only trusted input should be
653
 * fed to this function
654
 */
655
static int KECCAK_Deserialize(KECCAK1600_CTX *c, int impl_id,
656
    const unsigned char *input, size_t len)
657
0
{
658
0
    const unsigned char *p;
659
0
    uint64_t val;
660
0
    int i, j;
661
662
0
    if (c == NULL || input == NULL || len != KECCAK_SERIALIZATION_LEN)
663
0
        return 0;
664
665
    /* Magic code */
666
0
    if (memcmp(input, keccakmagic, KECCAKMAGIC_LEN) != 0)
667
0
        return 0;
668
669
0
    p = input + KECCAKMAGIC_LEN;
670
671
    /* Check for matching Impl ID */
672
0
    p = OPENSSL_load_u64_le(&val, p);
673
0
    if (val != (uint64_t)impl_id)
674
0
        return 0;
675
676
    /* Check for matching md_size */
677
0
    p = OPENSSL_load_u64_le(&val, p);
678
0
    if (val != (uint64_t)c->md_size)
679
0
        return 0;
680
681
    /* check that block_size is congruent with the initialized value */
682
0
    p = OPENSSL_load_u64_le(&val, p);
683
0
    if (val != c->block_size)
684
0
        return 0;
685
    /* check that bufsz does not exceed block_size */
686
0
    p = OPENSSL_load_u64_le(&val, p);
687
0
    if (val > c->block_size)
688
0
        return 0;
689
0
    c->bufsz = (size_t)val;
690
0
    p = OPENSSL_load_u64_le(&val, p);
691
0
    if (val != c->pad)
692
0
        return 0;
693
0
    p = OPENSSL_load_u64_le(&val, p);
694
0
    c->xof_state = (int)val;
695
696
    /* A matrix */
697
0
    for (i = 0; i < 5; i++) {
698
0
        for (j = 0; j < 5; j++) {
699
0
            p = OPENSSL_load_u64_le(&val, p);
700
0
            c->A[i][j] = val;
701
0
        }
702
0
    }
703
704
    /* buf */
705
0
    memcpy(c->buf, p, sizeof(c->buf));
706
707
0
    return 1;
708
0
}
709
710
#define IMPLEMENT_SERIALIZE_FNS(name, id)                              \
711
    static int name##_serialize(void *vctx, unsigned char *out,        \
712
        size_t *outlen)                                                \
713
0
    {                                                                  \
714
0
        return KECCAK_Serialize(vctx, id, out, outlen);                \
715
0
    }                                                                  \
Unexecuted instantiation: sha3_prov.c:sha3_224_serialize
Unexecuted instantiation: sha3_prov.c:sha3_256_serialize
Unexecuted instantiation: sha3_prov.c:sha3_384_serialize
Unexecuted instantiation: sha3_prov.c:sha3_512_serialize
Unexecuted instantiation: sha3_prov.c:keccak_224_serialize
Unexecuted instantiation: sha3_prov.c:keccak_256_serialize
Unexecuted instantiation: sha3_prov.c:keccak_384_serialize
Unexecuted instantiation: sha3_prov.c:keccak_512_serialize
Unexecuted instantiation: sha3_prov.c:shake_128_serialize
Unexecuted instantiation: sha3_prov.c:shake_256_serialize
Unexecuted instantiation: sha3_prov.c:cshake_keccak_128_serialize
Unexecuted instantiation: sha3_prov.c:cshake_keccak_256_serialize
716
    static int name##_deserialize(void *vctx, const unsigned char *in, \
717
        size_t inlen)                                                  \
718
0
    {                                                                  \
719
0
        return KECCAK_Deserialize(vctx, id, in, inlen);                \
720
0
    }
Unexecuted instantiation: sha3_prov.c:sha3_224_deserialize
Unexecuted instantiation: sha3_prov.c:sha3_256_deserialize
Unexecuted instantiation: sha3_prov.c:sha3_384_deserialize
Unexecuted instantiation: sha3_prov.c:sha3_512_deserialize
Unexecuted instantiation: sha3_prov.c:keccak_224_deserialize
Unexecuted instantiation: sha3_prov.c:keccak_256_deserialize
Unexecuted instantiation: sha3_prov.c:keccak_384_deserialize
Unexecuted instantiation: sha3_prov.c:keccak_512_deserialize
Unexecuted instantiation: sha3_prov.c:shake_128_deserialize
Unexecuted instantiation: sha3_prov.c:shake_256_deserialize
Unexecuted instantiation: sha3_prov.c:cshake_keccak_128_deserialize
Unexecuted instantiation: sha3_prov.c:cshake_keccak_256_deserialize
721
722
static const OSSL_PARAM *shake_gettable_ctx_params(ossl_unused void *ctx,
723
    ossl_unused void *provctx)
724
8
{
725
8
    return shake_get_ctx_params_list;
726
8
}
727
728
static int shake_get_ctx_params(void *vctx, OSSL_PARAM params[])
729
8
{
730
8
    struct shake_get_ctx_params_st p;
731
8
    KECCAK1600_CTX *ctx = (KECCAK1600_CTX *)vctx;
732
733
8
    if (ctx == NULL || !shake_get_ctx_params_decoder(params, &p))
734
0
        return 0;
735
736
8
    if (p.xoflen != NULL && !OSSL_PARAM_set_size_t(p.xoflen, ctx->md_size)) {
737
0
        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
738
0
        return 0;
739
0
    }
740
    /* Size is an alias of xoflen but separate them for compatibility */
741
8
    if (p.size != NULL && !OSSL_PARAM_set_size_t(p.size, ctx->md_size)) {
742
0
        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
743
0
        return 0;
744
0
    }
745
8
    return 1;
746
8
}
747
748
static const OSSL_PARAM *shake_settable_ctx_params(ossl_unused void *ctx,
749
    ossl_unused void *provctx)
750
0
{
751
0
    return shake_set_ctx_params_list;
752
0
}
753
754
static int shake_set_ctx_params(void *vctx, const OSSL_PARAM params[])
755
4
{
756
4
    struct shake_set_ctx_params_st p;
757
4
    KECCAK1600_CTX *ctx = (KECCAK1600_CTX *)vctx;
758
759
4
    if (ossl_unlikely(ctx == NULL || !shake_set_ctx_params_decoder(params, &p)))
760
0
        return 0;
761
762
4
    if (ossl_unlikely(p.xoflen != NULL
763
4
            && !OSSL_PARAM_get_size_t(p.xoflen, &ctx->md_size))) {
764
0
        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
765
0
        return 0;
766
0
    }
767
4
    return 1;
768
4
}
769
770
#define KECCAK_SER_ID 0x010000
771
#define SHAKE_SER_ID 0x020000
772
#define SHA3_SER_ID 0x040000
773
#define CSHAKE_KECCAK_SER_ID 0x080000
774
775
#define IMPLEMENT_SHA3_functions(bitlen)                                           \
776
    SHA3_newctx(sha3, SHA3_##bitlen, sha3_##bitlen, bitlen, (uint8_t)SHA3_PADDING) \
777
        IMPLEMENT_SERIALIZE_FNS(sha3_##bitlen, SHA3_SER_ID + bitlen)               \
778
            PROV_FUNC_SHA3_DIGEST(sha3_##bitlen, bitlen,                           \
779
                SHA3_BLOCKSIZE(bitlen), SHA3_MDSIZE(bitlen),                       \
780
                SHA3_FLAGS)
781
782
#define IMPLEMENT_KECCAK_functions(bitlen)                                                 \
783
    SHA3_newctx(keccak, KECCAK_##bitlen, keccak_##bitlen, bitlen, (uint8_t)KECCAK_PADDING) \
784
        IMPLEMENT_SERIALIZE_FNS(keccak_##bitlen, KECCAK_SER_ID + bitlen)                   \
785
            PROV_FUNC_SHA3_DIGEST(keccak_##bitlen, bitlen,                                 \
786
                SHA3_BLOCKSIZE(bitlen), SHA3_MDSIZE(bitlen),                               \
787
                SHA3_FLAGS)
788
789
#define IMPLEMENT_SHAKE_functions(bitlen)                              \
790
    SHAKE_newctx(shake, SHAKE_##bitlen, shake_##bitlen, bitlen,        \
791
        0 /* no default md length */, (uint8_t)SHAKE_PADDING)          \
792
        IMPLEMENT_SERIALIZE_FNS(shake_##bitlen, SHAKE_SER_ID + bitlen) \
793
            PROV_FUNC_SHAKE_DIGEST(shake_##bitlen, bitlen,             \
794
                SHA3_BLOCKSIZE(bitlen), 0,                             \
795
                SHAKE_FLAGS)
796
797
#define IMPLEMENT_CSHAKE_KECCAK_functions(bitlen)                                        \
798
    CSHAKE_KECCAK_newctx(cshake_keccak_##bitlen, bitlen, (uint8_t)CSHAKE_KECCAK_PADDING) \
799
        IMPLEMENT_SERIALIZE_FNS(cshake_keccak_##bitlen, CSHAKE_KECCAK_SER_ID + bitlen)   \
800
            PROV_FUNC_SHAKE_DIGEST(cshake_keccak_##bitlen, bitlen,                       \
801
                SHA3_BLOCKSIZE(bitlen),                                                  \
802
                CSHAKE_KECCAK_MDSIZE(bitlen),                                            \
803
                CSHAKE_KECCAK_FLAGS)
804
805
/* ossl_sha3_224_functions */
806
16
IMPLEMENT_SHA3_functions(224)
807
16
/* ossl_sha3_256_functions */
808
16
IMPLEMENT_SHA3_functions(256)
809
4
/* ossl_sha3_384_functions */
810
26
IMPLEMENT_SHA3_functions(384)
811
26
/* ossl_sha3_512_functions */
812
26
IMPLEMENT_SHA3_functions(512)
813
9
/* ossl_keccak_224_functions */
814
9
IMPLEMENT_KECCAK_functions(224)
815
0
/* ossl_keccak_256_functions */
816
0
IMPLEMENT_KECCAK_functions(256)
817
0
/* ossl_keccak_384_functions */
818
0
IMPLEMENT_KECCAK_functions(384)
819
0
/* ossl_keccak_512_functions */
820
0
IMPLEMENT_KECCAK_functions(512)
821
0
/* ossl_shake_128_functions */
822
2
IMPLEMENT_SHAKE_functions(128)
823
2
/* ossl_shake_256_functions */
824
6
IMPLEMENT_SHAKE_functions(256)
825
6
/* ossl_cshake_keccak_128_functions */
826
6
IMPLEMENT_CSHAKE_KECCAK_functions(128)
827
0
    /* ossl_cshake_keccak_256_functions */
828
    IMPLEMENT_CSHAKE_KECCAK_functions(256)