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