Path: blob/main/crypto/openssl/providers/implementations/digests/sha3_prov.c
48383 views
/*1* Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.2*3* Licensed under the Apache License 2.0 (the "License"). You may not use4* this file except in compliance with the License. You can obtain a copy5* in the file LICENSE in the source distribution or at6* https://www.openssl.org/source/license.html7*/89#include <string.h>10#include <openssl/core_names.h>11#include <openssl/crypto.h>12#include <openssl/evp.h>13#include <openssl/params.h>14#include <openssl/err.h>15#include <openssl/proverr.h>16#include "internal/numbers.h"17#include "internal/sha3.h"18#include "prov/digestcommon.h"19#include "prov/implementations.h"2021#define SHA3_FLAGS PROV_DIGEST_FLAG_ALGID_ABSENT22#define SHAKE_FLAGS (PROV_DIGEST_FLAG_XOF | PROV_DIGEST_FLAG_ALGID_ABSENT)23#define KMAC_FLAGS PROV_DIGEST_FLAG_XOF2425/*26* Forward declaration of any unique methods implemented here. This is not strictly27* necessary for the compiler, but provides an assurance that the signatures28* of the functions in the dispatch table are correct.29*/30static OSSL_FUNC_digest_init_fn keccak_init;31static OSSL_FUNC_digest_init_fn keccak_init_params;32static OSSL_FUNC_digest_update_fn keccak_update;33static OSSL_FUNC_digest_final_fn keccak_final;34static OSSL_FUNC_digest_freectx_fn keccak_freectx;35static OSSL_FUNC_digest_copyctx_fn keccak_copyctx;36static OSSL_FUNC_digest_dupctx_fn keccak_dupctx;37static OSSL_FUNC_digest_squeeze_fn shake_squeeze;38static OSSL_FUNC_digest_get_ctx_params_fn shake_get_ctx_params;39static OSSL_FUNC_digest_gettable_ctx_params_fn shake_gettable_ctx_params;40static OSSL_FUNC_digest_set_ctx_params_fn shake_set_ctx_params;41static OSSL_FUNC_digest_settable_ctx_params_fn shake_settable_ctx_params;42static sha3_absorb_fn generic_sha3_absorb;43static sha3_final_fn generic_sha3_final;44static sha3_squeeze_fn generic_sha3_squeeze;4546#if defined(OPENSSL_CPUID_OBJ) && defined(__s390__) && defined(KECCAK1600_ASM)47/*48* IBM S390X support49*/50# include "s390x_arch.h"51# define S390_SHA3 152# define S390_SHA3_CAPABLE(name) \53((OPENSSL_s390xcap_P.kimd[0] & S390X_CAPBIT(S390X_##name)) && \54(OPENSSL_s390xcap_P.klmd[0] & S390X_CAPBIT(S390X_##name)))5556#endif5758static int keccak_init(void *vctx, ossl_unused const OSSL_PARAM params[])59{60if (!ossl_prov_is_running())61return 0;62/* The newctx() handles most of the ctx fixed setup. */63ossl_sha3_reset((KECCAK1600_CTX *)vctx);64return 1;65}6667static int keccak_init_params(void *vctx, const OSSL_PARAM params[])68{69return keccak_init(vctx, NULL)70&& shake_set_ctx_params(vctx, params);71}7273static int keccak_update(void *vctx, const unsigned char *inp, size_t len)74{75KECCAK1600_CTX *ctx = vctx;76const size_t bsz = ctx->block_size;77size_t num, rem;7879if (len == 0)80return 1;8182/* Is there anything in the buffer already ? */83if ((num = ctx->bufsz) != 0) {84/* Calculate how much space is left in the buffer */85rem = bsz - num;86/* If the new input does not fill the buffer then just add it */87if (len < rem) {88memcpy(ctx->buf + num, inp, len);89ctx->bufsz += len;90return 1;91}92/* otherwise fill up the buffer and absorb the buffer */93memcpy(ctx->buf + num, inp, rem);94/* Update the input pointer */95inp += rem;96len -= rem;97ctx->meth.absorb(ctx, ctx->buf, bsz);98ctx->bufsz = 0;99}100/* Absorb the input - rem = leftover part of the input < blocksize) */101rem = ctx->meth.absorb(ctx, inp, len);102/* Copy the leftover bit of the input into the buffer */103if (rem) {104memcpy(ctx->buf, inp + len - rem, rem);105ctx->bufsz = rem;106}107return 1;108}109110static int keccak_final(void *vctx, unsigned char *out, size_t *outl,111size_t outlen)112{113int ret = 1;114KECCAK1600_CTX *ctx = vctx;115116if (!ossl_prov_is_running())117return 0;118if (ctx->md_size == SIZE_MAX) {119ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_LENGTH);120return 0;121}122if (outlen > 0)123ret = ctx->meth.final(ctx, out, ctx->md_size);124125*outl = ctx->md_size;126return ret;127}128129static int shake_squeeze(void *vctx, unsigned char *out, size_t *outl,130size_t outlen)131{132int ret = 1;133KECCAK1600_CTX *ctx = vctx;134135if (!ossl_prov_is_running())136return 0;137if (ctx->meth.squeeze == NULL)138return 0;139if (outlen > 0)140ret = ctx->meth.squeeze(ctx, out, outlen);141142*outl = outlen;143return ret;144}145146/*-147* Generic software version of the absorb() and final().148*/149static size_t generic_sha3_absorb(void *vctx, const void *inp, size_t len)150{151KECCAK1600_CTX *ctx = vctx;152153if (!(ctx->xof_state == XOF_STATE_INIT ||154ctx->xof_state == XOF_STATE_ABSORB))155return 0;156ctx->xof_state = XOF_STATE_ABSORB;157return SHA3_absorb(ctx->A, inp, len, ctx->block_size);158}159160static int generic_sha3_final(void *vctx, unsigned char *out, size_t outlen)161{162return ossl_sha3_final((KECCAK1600_CTX *)vctx, out, outlen);163}164165static int generic_sha3_squeeze(void *vctx, unsigned char *out, size_t outlen)166{167return ossl_sha3_squeeze((KECCAK1600_CTX *)vctx, out, outlen);168}169170static PROV_SHA3_METHOD sha3_generic_md = {171generic_sha3_absorb,172generic_sha3_final,173NULL174};175176static PROV_SHA3_METHOD shake_generic_md =177{178generic_sha3_absorb,179generic_sha3_final,180generic_sha3_squeeze181};182183#if defined(S390_SHA3)184185static sha3_absorb_fn s390x_sha3_absorb;186static sha3_final_fn s390x_sha3_final;187static sha3_final_fn s390x_shake_final;188189/*-190* The platform specific parts of the absorb() and final() for S390X.191*/192static size_t s390x_sha3_absorb(void *vctx, const void *inp, size_t len)193{194KECCAK1600_CTX *ctx = vctx;195size_t rem = len % ctx->block_size;196unsigned int fc;197198if (!(ctx->xof_state == XOF_STATE_INIT ||199ctx->xof_state == XOF_STATE_ABSORB))200return 0;201if (len - rem > 0) {202fc = ctx->pad;203fc |= ctx->xof_state == XOF_STATE_INIT ? S390X_KIMD_NIP : 0;204ctx->xof_state = XOF_STATE_ABSORB;205s390x_kimd(inp, len - rem, fc, ctx->A);206}207return rem;208}209210static int s390x_sha3_final(void *vctx, unsigned char *out, size_t outlen)211{212KECCAK1600_CTX *ctx = vctx;213unsigned int fc;214215if (!ossl_prov_is_running())216return 0;217if (!(ctx->xof_state == XOF_STATE_INIT ||218ctx->xof_state == XOF_STATE_ABSORB))219return 0;220fc = ctx->pad | S390X_KLMD_DUFOP;221fc |= ctx->xof_state == XOF_STATE_INIT ? S390X_KLMD_NIP : 0;222ctx->xof_state = XOF_STATE_FINAL;223s390x_klmd(ctx->buf, ctx->bufsz, NULL, 0, fc, ctx->A);224memcpy(out, ctx->A, outlen);225return 1;226}227228static int s390x_shake_final(void *vctx, unsigned char *out, size_t outlen)229{230KECCAK1600_CTX *ctx = vctx;231unsigned int fc;232233if (!ossl_prov_is_running())234return 0;235if (!(ctx->xof_state == XOF_STATE_INIT ||236ctx->xof_state == XOF_STATE_ABSORB))237return 0;238fc = ctx->pad | S390X_KLMD_DUFOP;239fc |= ctx->xof_state == XOF_STATE_INIT ? S390X_KLMD_NIP : 0;240ctx->xof_state = XOF_STATE_FINAL;241s390x_klmd(ctx->buf, ctx->bufsz, out, outlen, fc, ctx->A);242return 1;243}244245static int s390x_shake_squeeze(void *vctx, unsigned char *out, size_t outlen)246{247KECCAK1600_CTX *ctx = vctx;248unsigned int fc;249size_t len;250251if (!ossl_prov_is_running())252return 0;253if (ctx->xof_state == XOF_STATE_FINAL)254return 0;255/*256* On the first squeeze call, finish the absorb process (incl. padding).257*/258if (ctx->xof_state != XOF_STATE_SQUEEZE) {259fc = ctx->pad;260fc |= ctx->xof_state == XOF_STATE_INIT ? S390X_KLMD_NIP : 0;261ctx->xof_state = XOF_STATE_SQUEEZE;262s390x_klmd(ctx->buf, ctx->bufsz, out, outlen, fc, ctx->A);263ctx->bufsz = outlen % ctx->block_size;264/* reuse ctx->bufsz to count bytes squeezed from current sponge */265return 1;266}267ctx->xof_state = XOF_STATE_SQUEEZE;268if (ctx->bufsz != 0) {269len = ctx->block_size - ctx->bufsz;270if (outlen < len)271len = outlen;272memcpy(out, (char *)ctx->A + ctx->bufsz, len);273out += len;274outlen -= len;275ctx->bufsz += len;276if (ctx->bufsz == ctx->block_size)277ctx->bufsz = 0;278}279if (outlen == 0)280return 1;281s390x_klmd(NULL, 0, out, outlen, ctx->pad | S390X_KLMD_PS, ctx->A);282ctx->bufsz = outlen % ctx->block_size;283284return 1;285}286287static int s390x_keccakc_final(void *vctx, unsigned char *out, size_t outlen,288int padding)289{290KECCAK1600_CTX *ctx = vctx;291size_t bsz = ctx->block_size;292size_t num = ctx->bufsz;293size_t needed = outlen;294unsigned int fc;295296if (!ossl_prov_is_running())297return 0;298if (!(ctx->xof_state == XOF_STATE_INIT ||299ctx->xof_state == XOF_STATE_ABSORB))300return 0;301fc = ctx->pad;302fc |= ctx->xof_state == XOF_STATE_INIT ? S390X_KIMD_NIP : 0;303ctx->xof_state = XOF_STATE_FINAL;304if (outlen == 0)305return 1;306memset(ctx->buf + num, 0, bsz - num);307ctx->buf[num] = padding;308ctx->buf[bsz - 1] |= 0x80;309s390x_kimd(ctx->buf, bsz, fc, ctx->A);310num = needed > bsz ? bsz : needed;311memcpy(out, ctx->A, num);312needed -= num;313if (needed > 0)314s390x_klmd(NULL, 0, out + bsz, needed,315ctx->pad | S390X_KLMD_PS | S390X_KLMD_DUFOP, ctx->A);316317return 1;318}319320static int s390x_keccak_final(void *vctx, unsigned char *out, size_t outlen)321{322return s390x_keccakc_final(vctx, out, outlen, 0x01);323}324325static int s390x_kmac_final(void *vctx, unsigned char *out, size_t outlen)326{327return s390x_keccakc_final(vctx, out, outlen, 0x04);328}329330static int s390x_keccakc_squeeze(void *vctx, unsigned char *out, size_t outlen,331int padding)332{333KECCAK1600_CTX *ctx = vctx;334size_t len;335unsigned int fc;336337if (!ossl_prov_is_running())338return 0;339if (ctx->xof_state == XOF_STATE_FINAL)340return 0;341/*342* On the first squeeze call, finish the absorb process343* by adding the trailing padding and then doing344* a final absorb.345*/346if (ctx->xof_state != XOF_STATE_SQUEEZE) {347len = ctx->block_size - ctx->bufsz;348memset(ctx->buf + ctx->bufsz, 0, len);349ctx->buf[ctx->bufsz] = padding;350ctx->buf[ctx->block_size - 1] |= 0x80;351fc = ctx->pad;352fc |= ctx->xof_state == XOF_STATE_INIT ? S390X_KIMD_NIP : 0;353s390x_kimd(ctx->buf, ctx->block_size, fc, ctx->A);354ctx->bufsz = 0;355/* reuse ctx->bufsz to count bytes squeezed from current sponge */356}357if (ctx->bufsz != 0 || ctx->xof_state != XOF_STATE_SQUEEZE) {358len = ctx->block_size - ctx->bufsz;359if (outlen < len)360len = outlen;361memcpy(out, (char *)ctx->A + ctx->bufsz, len);362out += len;363outlen -= len;364ctx->bufsz += len;365if (ctx->bufsz == ctx->block_size)366ctx->bufsz = 0;367}368ctx->xof_state = XOF_STATE_SQUEEZE;369if (outlen == 0)370return 1;371s390x_klmd(NULL, 0, out, outlen, ctx->pad | S390X_KLMD_PS, ctx->A);372ctx->bufsz = outlen % ctx->block_size;373374return 1;375}376377static int s390x_keccak_squeeze(void *vctx, unsigned char *out, size_t outlen)378{379return s390x_keccakc_squeeze(vctx, out, outlen, 0x01);380}381382static int s390x_kmac_squeeze(void *vctx, unsigned char *out, size_t outlen)383{384return s390x_keccakc_squeeze(vctx, out, outlen, 0x04);385}386387static PROV_SHA3_METHOD sha3_s390x_md = {388s390x_sha3_absorb,389s390x_sha3_final,390NULL,391};392393static PROV_SHA3_METHOD keccak_s390x_md = {394s390x_sha3_absorb,395s390x_keccak_final,396s390x_keccak_squeeze,397};398399static PROV_SHA3_METHOD shake_s390x_md = {400s390x_sha3_absorb,401s390x_shake_final,402s390x_shake_squeeze,403};404405static PROV_SHA3_METHOD kmac_s390x_md = {406s390x_sha3_absorb,407s390x_kmac_final,408s390x_kmac_squeeze,409};410411# define SHAKE_SET_MD(uname, typ) \412if (S390_SHA3_CAPABLE(uname)) { \413ctx->pad = S390X_##uname; \414ctx->meth = typ##_s390x_md; \415} else { \416ctx->meth = shake_generic_md; \417}418419# define SHA3_SET_MD(uname, typ) \420if (S390_SHA3_CAPABLE(uname)) { \421ctx->pad = S390X_##uname; \422ctx->meth = typ##_s390x_md; \423} else { \424ctx->meth = sha3_generic_md; \425}426# define KMAC_SET_MD(bitlen) \427if (S390_SHA3_CAPABLE(SHAKE_##bitlen)) { \428ctx->pad = S390X_SHAKE_##bitlen; \429ctx->meth = kmac_s390x_md; \430} else { \431ctx->meth = sha3_generic_md; \432}433#elif defined(__aarch64__) && defined(KECCAK1600_ASM)434# include "arm_arch.h"435436static sha3_absorb_fn armsha3_sha3_absorb;437438size_t SHA3_absorb_cext(uint64_t A[5][5], const unsigned char *inp, size_t len,439size_t r);440/*-441* Hardware-assisted ARMv8.2 SHA3 extension version of the absorb()442*/443static size_t armsha3_sha3_absorb(void *vctx, const void *inp, size_t len)444{445KECCAK1600_CTX *ctx = vctx;446447return SHA3_absorb_cext(ctx->A, inp, len, ctx->block_size);448}449450static PROV_SHA3_METHOD sha3_ARMSHA3_md = {451armsha3_sha3_absorb,452generic_sha3_final453};454static PROV_SHA3_METHOD shake_ARMSHA3_md =455{456armsha3_sha3_absorb,457generic_sha3_final,458generic_sha3_squeeze459};460# define SHAKE_SET_MD(uname, typ) \461if (OPENSSL_armcap_P & ARMV8_HAVE_SHA3_AND_WORTH_USING) { \462ctx->meth = shake_ARMSHA3_md; \463} else { \464ctx->meth = shake_generic_md; \465}466467# define SHA3_SET_MD(uname, typ) \468if (OPENSSL_armcap_P & ARMV8_HAVE_SHA3_AND_WORTH_USING) { \469ctx->meth = sha3_ARMSHA3_md; \470} else { \471ctx->meth = sha3_generic_md; \472}473# define KMAC_SET_MD(bitlen) \474if (OPENSSL_armcap_P & ARMV8_HAVE_SHA3_AND_WORTH_USING) { \475ctx->meth = sha3_ARMSHA3_md; \476} else { \477ctx->meth = sha3_generic_md; \478}479#else480# define SHA3_SET_MD(uname, typ) ctx->meth = sha3_generic_md;481# define KMAC_SET_MD(bitlen) ctx->meth = sha3_generic_md;482# define SHAKE_SET_MD(uname, typ) ctx->meth = shake_generic_md;483#endif /* S390_SHA3 */484485#define SHA3_newctx(typ, uname, name, bitlen, pad) \486static OSSL_FUNC_digest_newctx_fn name##_newctx; \487static void *name##_newctx(void *provctx) \488{ \489KECCAK1600_CTX *ctx = ossl_prov_is_running() ? OPENSSL_zalloc(sizeof(*ctx)) \490: NULL; \491\492if (ctx == NULL) \493return NULL; \494ossl_sha3_init(ctx, pad, bitlen); \495SHA3_SET_MD(uname, typ) \496return ctx; \497}498499#define SHAKE_newctx(typ, uname, name, bitlen, mdlen, pad) \500static OSSL_FUNC_digest_newctx_fn name##_newctx; \501static void *name##_newctx(void *provctx) \502{ \503KECCAK1600_CTX *ctx = ossl_prov_is_running() ? OPENSSL_zalloc(sizeof(*ctx))\504: NULL; \505\506if (ctx == NULL) \507return NULL; \508ossl_keccak_init(ctx, pad, bitlen, mdlen); \509if (mdlen == 0) \510ctx->md_size = SIZE_MAX; \511SHAKE_SET_MD(uname, typ) \512return ctx; \513}514515#define KMAC_newctx(uname, bitlen, pad) \516static OSSL_FUNC_digest_newctx_fn uname##_newctx; \517static void *uname##_newctx(void *provctx) \518{ \519KECCAK1600_CTX *ctx = ossl_prov_is_running() ? OPENSSL_zalloc(sizeof(*ctx)) \520: NULL; \521\522if (ctx == NULL) \523return NULL; \524ossl_keccak_init(ctx, pad, bitlen, 2 * bitlen); \525KMAC_SET_MD(bitlen) \526return ctx; \527}528529#define PROV_FUNC_SHA3_DIGEST_COMMON(name, bitlen, blksize, dgstsize, flags) \530PROV_FUNC_DIGEST_GET_PARAM(name, blksize, dgstsize, flags) \531const OSSL_DISPATCH ossl_##name##_functions[] = { \532{ OSSL_FUNC_DIGEST_NEWCTX, (void (*)(void))name##_newctx }, \533{ OSSL_FUNC_DIGEST_UPDATE, (void (*)(void))keccak_update }, \534{ OSSL_FUNC_DIGEST_FINAL, (void (*)(void))keccak_final }, \535{ OSSL_FUNC_DIGEST_FREECTX, (void (*)(void))keccak_freectx }, \536{ OSSL_FUNC_DIGEST_DUPCTX, (void (*)(void))keccak_dupctx }, \537{ OSSL_FUNC_DIGEST_COPYCTX, (void (*)(void))keccak_copyctx }, \538PROV_DISPATCH_FUNC_DIGEST_GET_PARAMS(name)539540#define PROV_FUNC_SHA3_DIGEST(name, bitlen, blksize, dgstsize, flags) \541PROV_FUNC_SHA3_DIGEST_COMMON(name, bitlen, blksize, dgstsize, flags), \542{ OSSL_FUNC_DIGEST_INIT, (void (*)(void))keccak_init }, \543PROV_DISPATCH_FUNC_DIGEST_CONSTRUCT_END544545#define PROV_FUNC_SHAKE_DIGEST(name, bitlen, blksize, dgstsize, flags) \546PROV_FUNC_SHA3_DIGEST_COMMON(name, bitlen, blksize, dgstsize, flags), \547{ OSSL_FUNC_DIGEST_SQUEEZE, (void (*)(void))shake_squeeze }, \548{ OSSL_FUNC_DIGEST_INIT, (void (*)(void))keccak_init_params }, \549{ OSSL_FUNC_DIGEST_SET_CTX_PARAMS, (void (*)(void))shake_set_ctx_params }, \550{ OSSL_FUNC_DIGEST_SETTABLE_CTX_PARAMS, \551(void (*)(void))shake_settable_ctx_params }, \552{ OSSL_FUNC_DIGEST_GET_CTX_PARAMS, (void (*)(void))shake_get_ctx_params }, \553{ OSSL_FUNC_DIGEST_GETTABLE_CTX_PARAMS, \554(void (*)(void))shake_gettable_ctx_params }, \555PROV_DISPATCH_FUNC_DIGEST_CONSTRUCT_END556557static void keccak_freectx(void *vctx)558{559KECCAK1600_CTX *ctx = (KECCAK1600_CTX *)vctx;560561OPENSSL_clear_free(ctx, sizeof(*ctx));562}563564static void keccak_copyctx(void *voutctx, void *vinctx)565{566KECCAK1600_CTX *outctx = (KECCAK1600_CTX *)voutctx;567KECCAK1600_CTX *inctx = (KECCAK1600_CTX *)vinctx;568569*outctx = *inctx;570}571572static void *keccak_dupctx(void *ctx)573{574KECCAK1600_CTX *in = (KECCAK1600_CTX *)ctx;575KECCAK1600_CTX *ret = ossl_prov_is_running() ? OPENSSL_malloc(sizeof(*ret))576: NULL;577578if (ret != NULL)579*ret = *in;580return ret;581}582583static const OSSL_PARAM *shake_gettable_ctx_params(ossl_unused void *ctx,584ossl_unused void *provctx)585{586static const OSSL_PARAM known_shake_gettable_ctx_params[] = {587{OSSL_DIGEST_PARAM_XOFLEN, OSSL_PARAM_UNSIGNED_INTEGER, NULL, 0, 0},588{OSSL_DIGEST_PARAM_SIZE, OSSL_PARAM_UNSIGNED_INTEGER, NULL, 0, 0},589OSSL_PARAM_END590};591return known_shake_gettable_ctx_params;592}593594static int shake_get_ctx_params(void *vctx, OSSL_PARAM params[])595{596OSSL_PARAM *p;597KECCAK1600_CTX *ctx = (KECCAK1600_CTX *)vctx;598599if (ctx == NULL)600return 0;601if (ossl_param_is_empty(params))602return 1;603604p = OSSL_PARAM_locate(params, OSSL_DIGEST_PARAM_XOFLEN);605if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->md_size)) {606ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);607return 0;608}609/* Size is an alias of xoflen */610p = OSSL_PARAM_locate(params, OSSL_DIGEST_PARAM_SIZE);611if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->md_size)) {612ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);613return 0;614}615return 1;616}617618static const OSSL_PARAM *shake_settable_ctx_params(ossl_unused void *ctx,619ossl_unused void *provctx)620{621static const OSSL_PARAM known_shake_settable_ctx_params[] = {622{OSSL_DIGEST_PARAM_XOFLEN, OSSL_PARAM_UNSIGNED_INTEGER, NULL, 0, 0},623{OSSL_DIGEST_PARAM_SIZE, OSSL_PARAM_UNSIGNED_INTEGER, NULL, 0, 0},624OSSL_PARAM_END625};626627return known_shake_settable_ctx_params;628}629630static int shake_set_ctx_params(void *vctx, const OSSL_PARAM params[])631{632const OSSL_PARAM *p;633KECCAK1600_CTX *ctx = (KECCAK1600_CTX *)vctx;634635if (ctx == NULL)636return 0;637if (ossl_param_is_empty(params))638return 1;639640p = OSSL_PARAM_locate_const(params, OSSL_DIGEST_PARAM_XOFLEN);641if (p == NULL)642p = OSSL_PARAM_locate_const(params, OSSL_DIGEST_PARAM_SIZE);643644if (p != NULL && !OSSL_PARAM_get_size_t(p, &ctx->md_size)) {645ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);646return 0;647}648return 1;649}650651#define IMPLEMENT_SHA3_functions(bitlen) \652SHA3_newctx(sha3, SHA3_##bitlen, sha3_##bitlen, bitlen, '\x06') \653PROV_FUNC_SHA3_DIGEST(sha3_##bitlen, bitlen, \654SHA3_BLOCKSIZE(bitlen), SHA3_MDSIZE(bitlen), \655SHA3_FLAGS)656657#define IMPLEMENT_KECCAK_functions(bitlen) \658SHA3_newctx(keccak, KECCAK_##bitlen, keccak_##bitlen, bitlen, '\x01') \659PROV_FUNC_SHA3_DIGEST(keccak_##bitlen, bitlen, \660SHA3_BLOCKSIZE(bitlen), SHA3_MDSIZE(bitlen), \661SHA3_FLAGS)662663#define IMPLEMENT_SHAKE_functions(bitlen) \664SHAKE_newctx(shake, SHAKE_##bitlen, shake_##bitlen, bitlen, \6650 /* no default md length */, '\x1f') \666PROV_FUNC_SHAKE_DIGEST(shake_##bitlen, bitlen, \667SHA3_BLOCKSIZE(bitlen), 0, \668SHAKE_FLAGS)669670#define IMPLEMENT_KMAC_functions(bitlen) \671KMAC_newctx(keccak_kmac_##bitlen, bitlen, '\x04') \672PROV_FUNC_SHAKE_DIGEST(keccak_kmac_##bitlen, bitlen, \673SHA3_BLOCKSIZE(bitlen), KMAC_MDSIZE(bitlen), \674KMAC_FLAGS)675676/* ossl_sha3_224_functions */677IMPLEMENT_SHA3_functions(224)678/* ossl_sha3_256_functions */679IMPLEMENT_SHA3_functions(256)680/* ossl_sha3_384_functions */681IMPLEMENT_SHA3_functions(384)682/* ossl_sha3_512_functions */683IMPLEMENT_SHA3_functions(512)684/* ossl_keccak_224_functions */685IMPLEMENT_KECCAK_functions(224)686/* ossl_keccak_256_functions */687IMPLEMENT_KECCAK_functions(256)688/* ossl_keccak_384_functions */689IMPLEMENT_KECCAK_functions(384)690/* ossl_keccak_512_functions */691IMPLEMENT_KECCAK_functions(512)692/* ossl_shake_128_functions */693IMPLEMENT_SHAKE_functions(128)694/* ossl_shake_256_functions */695IMPLEMENT_SHAKE_functions(256)696/* ossl_keccak_kmac_128_functions */697IMPLEMENT_KMAC_functions(128)698/* ossl_keccak_kmac_256_functions */699IMPLEMENT_KMAC_functions(256)700701702