Path: blob/main/crypto/openssl/providers/implementations/digests/sha3_prov.c
107228 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)) && (OPENSSL_s390xcap_P.klmd[0] & S390X_CAPBIT(S390X_##name)))5455#endif5657static int keccak_init(void *vctx, ossl_unused const OSSL_PARAM params[])58{59if (!ossl_prov_is_running())60return 0;61/* The newctx() handles most of the ctx fixed setup. */62ossl_sha3_reset((KECCAK1600_CTX *)vctx);63return 1;64}6566static int keccak_init_params(void *vctx, const OSSL_PARAM params[])67{68return keccak_init(vctx, NULL)69&& shake_set_ctx_params(vctx, params);70}7172static int keccak_update(void *vctx, const unsigned char *inp, size_t len)73{74KECCAK1600_CTX *ctx = vctx;75const size_t bsz = ctx->block_size;76size_t num, rem;7778if (len == 0)79return 1;8081/* Is there anything in the buffer already ? */82if ((num = ctx->bufsz) != 0) {83/* Calculate how much space is left in the buffer */84rem = bsz - num;85/* If the new input does not fill the buffer then just add it */86if (len < rem) {87memcpy(ctx->buf + num, inp, len);88ctx->bufsz += len;89return 1;90}91/* otherwise fill up the buffer and absorb the buffer */92memcpy(ctx->buf + num, inp, rem);93/* Update the input pointer */94inp += rem;95len -= rem;96ctx->meth.absorb(ctx, ctx->buf, bsz);97ctx->bufsz = 0;98}99/* Absorb the input - rem = leftover part of the input < blocksize) */100rem = ctx->meth.absorb(ctx, inp, len);101/* Copy the leftover bit of the input into the buffer */102if (rem) {103memcpy(ctx->buf, inp + len - rem, rem);104ctx->bufsz = rem;105}106return 1;107}108109static int keccak_final(void *vctx, unsigned char *out, size_t *outl,110size_t outlen)111{112int ret = 1;113KECCAK1600_CTX *ctx = vctx;114115if (!ossl_prov_is_running())116return 0;117if (ctx->md_size == SIZE_MAX) {118ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_LENGTH);119return 0;120}121if (outlen > 0)122ret = ctx->meth.final(ctx, out, ctx->md_size);123124*outl = ctx->md_size;125return ret;126}127128static int shake_squeeze(void *vctx, unsigned char *out, size_t *outl,129size_t outlen)130{131int ret = 1;132KECCAK1600_CTX *ctx = vctx;133134if (!ossl_prov_is_running())135return 0;136if (ctx->meth.squeeze == NULL)137return 0;138if (outlen > 0)139ret = ctx->meth.squeeze(ctx, out, outlen);140141*outl = outlen;142return ret;143}144145/*-146* Generic software version of the absorb() and final().147*/148static size_t generic_sha3_absorb(void *vctx, const void *inp, size_t len)149{150KECCAK1600_CTX *ctx = vctx;151152if (!(ctx->xof_state == XOF_STATE_INIT || ctx->xof_state == XOF_STATE_ABSORB))153return 0;154ctx->xof_state = XOF_STATE_ABSORB;155return SHA3_absorb(ctx->A, inp, len, ctx->block_size);156}157158static int generic_sha3_final(void *vctx, unsigned char *out, size_t outlen)159{160return ossl_sha3_final((KECCAK1600_CTX *)vctx, out, outlen);161}162163static int generic_sha3_squeeze(void *vctx, unsigned char *out, size_t outlen)164{165return ossl_sha3_squeeze((KECCAK1600_CTX *)vctx, out, outlen);166}167168static PROV_SHA3_METHOD sha3_generic_md = {169generic_sha3_absorb,170generic_sha3_final,171NULL172};173174static PROV_SHA3_METHOD shake_generic_md = {175generic_sha3_absorb,176generic_sha3_final,177generic_sha3_squeeze178};179180#if defined(S390_SHA3)181182static sha3_absorb_fn s390x_sha3_absorb;183static sha3_final_fn s390x_sha3_final;184static sha3_final_fn s390x_shake_final;185186/*-187* The platform specific parts of the absorb() and final() for S390X.188*/189static size_t s390x_sha3_absorb(void *vctx, const void *inp, size_t len)190{191KECCAK1600_CTX *ctx = vctx;192size_t rem = len % ctx->block_size;193unsigned int fc;194195if (!(ctx->xof_state == XOF_STATE_INIT || ctx->xof_state == XOF_STATE_ABSORB))196return 0;197if (len - rem > 0) {198fc = ctx->pad;199fc |= ctx->xof_state == XOF_STATE_INIT ? S390X_KIMD_NIP : 0;200ctx->xof_state = XOF_STATE_ABSORB;201s390x_kimd(inp, len - rem, fc, ctx->A);202}203return rem;204}205206static int s390x_sha3_final(void *vctx, unsigned char *out, size_t outlen)207{208KECCAK1600_CTX *ctx = vctx;209unsigned int fc;210211if (!ossl_prov_is_running())212return 0;213if (!(ctx->xof_state == XOF_STATE_INIT || ctx->xof_state == XOF_STATE_ABSORB))214return 0;215fc = ctx->pad | S390X_KLMD_DUFOP;216fc |= ctx->xof_state == XOF_STATE_INIT ? S390X_KLMD_NIP : 0;217ctx->xof_state = XOF_STATE_FINAL;218s390x_klmd(ctx->buf, ctx->bufsz, NULL, 0, fc, ctx->A);219memcpy(out, ctx->A, outlen);220return 1;221}222223static int s390x_shake_final(void *vctx, unsigned char *out, size_t outlen)224{225KECCAK1600_CTX *ctx = vctx;226unsigned int fc;227228if (!ossl_prov_is_running())229return 0;230if (!(ctx->xof_state == XOF_STATE_INIT || ctx->xof_state == XOF_STATE_ABSORB))231return 0;232fc = ctx->pad | S390X_KLMD_DUFOP;233fc |= ctx->xof_state == XOF_STATE_INIT ? S390X_KLMD_NIP : 0;234ctx->xof_state = XOF_STATE_FINAL;235s390x_klmd(ctx->buf, ctx->bufsz, out, outlen, fc, ctx->A);236return 1;237}238239static int s390x_shake_squeeze(void *vctx, unsigned char *out, size_t outlen)240{241KECCAK1600_CTX *ctx = vctx;242unsigned int fc;243size_t len;244245if (!ossl_prov_is_running())246return 0;247if (ctx->xof_state == XOF_STATE_FINAL)248return 0;249/*250* On the first squeeze call, finish the absorb process (incl. padding).251*/252if (ctx->xof_state != XOF_STATE_SQUEEZE) {253fc = ctx->pad;254fc |= ctx->xof_state == XOF_STATE_INIT ? S390X_KLMD_NIP : 0;255ctx->xof_state = XOF_STATE_SQUEEZE;256s390x_klmd(ctx->buf, ctx->bufsz, out, outlen, fc, ctx->A);257ctx->bufsz = outlen % ctx->block_size;258/* reuse ctx->bufsz to count bytes squeezed from current sponge */259return 1;260}261ctx->xof_state = XOF_STATE_SQUEEZE;262if (ctx->bufsz != 0) {263len = ctx->block_size - ctx->bufsz;264if (outlen < len)265len = outlen;266memcpy(out, (char *)ctx->A + ctx->bufsz, len);267out += len;268outlen -= len;269ctx->bufsz += len;270if (ctx->bufsz == ctx->block_size)271ctx->bufsz = 0;272}273if (outlen == 0)274return 1;275s390x_klmd(NULL, 0, out, outlen, ctx->pad | S390X_KLMD_PS, ctx->A);276ctx->bufsz = outlen % ctx->block_size;277278return 1;279}280281static int s390x_keccakc_final(void *vctx, unsigned char *out, size_t outlen,282int padding)283{284KECCAK1600_CTX *ctx = vctx;285size_t bsz = ctx->block_size;286size_t num = ctx->bufsz;287size_t needed = outlen;288unsigned int fc;289290if (!ossl_prov_is_running())291return 0;292if (!(ctx->xof_state == XOF_STATE_INIT || ctx->xof_state == XOF_STATE_ABSORB))293return 0;294fc = ctx->pad;295fc |= ctx->xof_state == XOF_STATE_INIT ? S390X_KIMD_NIP : 0;296ctx->xof_state = XOF_STATE_FINAL;297if (outlen == 0)298return 1;299memset(ctx->buf + num, 0, bsz - num);300ctx->buf[num] = padding;301ctx->buf[bsz - 1] |= 0x80;302s390x_kimd(ctx->buf, bsz, fc, ctx->A);303num = needed > bsz ? bsz : needed;304memcpy(out, ctx->A, num);305needed -= num;306if (needed > 0)307s390x_klmd(NULL, 0, out + bsz, needed,308ctx->pad | S390X_KLMD_PS | S390X_KLMD_DUFOP, ctx->A);309310return 1;311}312313static int s390x_keccak_final(void *vctx, unsigned char *out, size_t outlen)314{315return s390x_keccakc_final(vctx, out, outlen, 0x01);316}317318static int s390x_kmac_final(void *vctx, unsigned char *out, size_t outlen)319{320return s390x_keccakc_final(vctx, out, outlen, 0x04);321}322323static int s390x_keccakc_squeeze(void *vctx, unsigned char *out, size_t outlen,324int padding)325{326KECCAK1600_CTX *ctx = vctx;327size_t len;328unsigned int fc;329330if (!ossl_prov_is_running())331return 0;332if (ctx->xof_state == XOF_STATE_FINAL)333return 0;334/*335* On the first squeeze call, finish the absorb process336* by adding the trailing padding and then doing337* a final absorb.338*/339if (ctx->xof_state != XOF_STATE_SQUEEZE) {340len = ctx->block_size - ctx->bufsz;341memset(ctx->buf + ctx->bufsz, 0, len);342ctx->buf[ctx->bufsz] = padding;343ctx->buf[ctx->block_size - 1] |= 0x80;344fc = ctx->pad;345fc |= ctx->xof_state == XOF_STATE_INIT ? S390X_KIMD_NIP : 0;346s390x_kimd(ctx->buf, ctx->block_size, fc, ctx->A);347ctx->bufsz = 0;348/* reuse ctx->bufsz to count bytes squeezed from current sponge */349}350if (ctx->bufsz != 0 || ctx->xof_state != XOF_STATE_SQUEEZE) {351len = ctx->block_size - ctx->bufsz;352if (outlen < len)353len = outlen;354memcpy(out, (char *)ctx->A + ctx->bufsz, len);355out += len;356outlen -= len;357ctx->bufsz += len;358if (ctx->bufsz == ctx->block_size)359ctx->bufsz = 0;360}361ctx->xof_state = XOF_STATE_SQUEEZE;362if (outlen == 0)363return 1;364s390x_klmd(NULL, 0, out, outlen, ctx->pad | S390X_KLMD_PS, ctx->A);365ctx->bufsz = outlen % ctx->block_size;366367return 1;368}369370static int s390x_keccak_squeeze(void *vctx, unsigned char *out, size_t outlen)371{372return s390x_keccakc_squeeze(vctx, out, outlen, 0x01);373}374375static int s390x_kmac_squeeze(void *vctx, unsigned char *out, size_t outlen)376{377return s390x_keccakc_squeeze(vctx, out, outlen, 0x04);378}379380static PROV_SHA3_METHOD sha3_s390x_md = {381s390x_sha3_absorb,382s390x_sha3_final,383NULL,384};385386static PROV_SHA3_METHOD keccak_s390x_md = {387s390x_sha3_absorb,388s390x_keccak_final,389s390x_keccak_squeeze,390};391392static PROV_SHA3_METHOD shake_s390x_md = {393s390x_sha3_absorb,394s390x_shake_final,395s390x_shake_squeeze,396};397398static PROV_SHA3_METHOD kmac_s390x_md = {399s390x_sha3_absorb,400s390x_kmac_final,401s390x_kmac_squeeze,402};403404#define SHAKE_SET_MD(uname, typ) \405if (S390_SHA3_CAPABLE(uname)) { \406ctx->pad = S390X_##uname; \407ctx->meth = typ##_s390x_md; \408} else { \409ctx->meth = shake_generic_md; \410}411412#define SHA3_SET_MD(uname, typ) \413if (S390_SHA3_CAPABLE(uname)) { \414ctx->pad = S390X_##uname; \415ctx->meth = typ##_s390x_md; \416} else { \417ctx->meth = sha3_generic_md; \418}419#define KMAC_SET_MD(bitlen) \420if (S390_SHA3_CAPABLE(SHAKE_##bitlen)) { \421ctx->pad = S390X_SHAKE_##bitlen; \422ctx->meth = kmac_s390x_md; \423} else { \424ctx->meth = sha3_generic_md; \425}426#elif defined(__aarch64__) && defined(KECCAK1600_ASM)427#include "arm_arch.h"428429static sha3_absorb_fn armsha3_sha3_absorb;430431size_t SHA3_absorb_cext(uint64_t A[5][5], const unsigned char *inp, size_t len,432size_t r);433/*-434* Hardware-assisted ARMv8.2 SHA3 extension version of the absorb()435*/436static size_t armsha3_sha3_absorb(void *vctx, const void *inp, size_t len)437{438KECCAK1600_CTX *ctx = vctx;439440return SHA3_absorb_cext(ctx->A, inp, len, ctx->block_size);441}442443static PROV_SHA3_METHOD sha3_ARMSHA3_md = {444armsha3_sha3_absorb,445generic_sha3_final446};447static PROV_SHA3_METHOD shake_ARMSHA3_md = {448armsha3_sha3_absorb,449generic_sha3_final,450generic_sha3_squeeze451};452#define SHAKE_SET_MD(uname, typ) \453if (OPENSSL_armcap_P & ARMV8_HAVE_SHA3_AND_WORTH_USING) { \454ctx->meth = shake_ARMSHA3_md; \455} else { \456ctx->meth = shake_generic_md; \457}458459#define SHA3_SET_MD(uname, typ) \460if (OPENSSL_armcap_P & ARMV8_HAVE_SHA3_AND_WORTH_USING) { \461ctx->meth = sha3_ARMSHA3_md; \462} else { \463ctx->meth = sha3_generic_md; \464}465#define KMAC_SET_MD(bitlen) \466if (OPENSSL_armcap_P & ARMV8_HAVE_SHA3_AND_WORTH_USING) { \467ctx->meth = sha3_ARMSHA3_md; \468} else { \469ctx->meth = sha3_generic_md; \470}471#else472#define SHA3_SET_MD(uname, typ) ctx->meth = sha3_generic_md;473#define KMAC_SET_MD(bitlen) ctx->meth = sha3_generic_md;474#define SHAKE_SET_MD(uname, typ) ctx->meth = shake_generic_md;475#endif /* S390_SHA3 */476477#define SHA3_newctx(typ, uname, name, bitlen, pad) \478static OSSL_FUNC_digest_newctx_fn name##_newctx; \479static void *name##_newctx(void *provctx) \480{ \481KECCAK1600_CTX *ctx = ossl_prov_is_running() ? OPENSSL_zalloc(sizeof(*ctx)) \482: NULL; \483\484if (ctx == NULL) \485return NULL; \486ossl_sha3_init(ctx, pad, bitlen); \487SHA3_SET_MD(uname, typ) \488return ctx; \489}490491#define SHAKE_newctx(typ, uname, name, bitlen, mdlen, pad) \492static OSSL_FUNC_digest_newctx_fn name##_newctx; \493static void *name##_newctx(void *provctx) \494{ \495KECCAK1600_CTX *ctx = ossl_prov_is_running() ? OPENSSL_zalloc(sizeof(*ctx)) \496: NULL; \497\498if (ctx == NULL) \499return NULL; \500ossl_keccak_init(ctx, pad, bitlen, mdlen); \501if (mdlen == 0) \502ctx->md_size = SIZE_MAX; \503SHAKE_SET_MD(uname, typ) \504return ctx; \505}506507#define KMAC_newctx(uname, bitlen, pad) \508static OSSL_FUNC_digest_newctx_fn uname##_newctx; \509static void *uname##_newctx(void *provctx) \510{ \511KECCAK1600_CTX *ctx = ossl_prov_is_running() ? OPENSSL_zalloc(sizeof(*ctx)) \512: NULL; \513\514if (ctx == NULL) \515return NULL; \516ossl_keccak_init(ctx, pad, bitlen, 2 * bitlen); \517KMAC_SET_MD(bitlen) \518return ctx; \519}520521#define PROV_FUNC_SHA3_DIGEST_COMMON(name, bitlen, blksize, dgstsize, flags) \522PROV_FUNC_DIGEST_GET_PARAM(name, blksize, dgstsize, flags) \523const OSSL_DISPATCH ossl_##name##_functions[] = { \524{ OSSL_FUNC_DIGEST_NEWCTX, (void (*)(void))name##_newctx }, \525{ OSSL_FUNC_DIGEST_UPDATE, (void (*)(void))keccak_update }, \526{ OSSL_FUNC_DIGEST_FINAL, (void (*)(void))keccak_final }, \527{ OSSL_FUNC_DIGEST_FREECTX, (void (*)(void))keccak_freectx }, \528{ OSSL_FUNC_DIGEST_DUPCTX, (void (*)(void))keccak_dupctx }, \529{ OSSL_FUNC_DIGEST_COPYCTX, (void (*)(void))keccak_copyctx }, \530PROV_DISPATCH_FUNC_DIGEST_GET_PARAMS(name)531532#define PROV_FUNC_SHA3_DIGEST(name, bitlen, blksize, dgstsize, flags) \533PROV_FUNC_SHA3_DIGEST_COMMON(name, bitlen, blksize, dgstsize, flags), \534{ OSSL_FUNC_DIGEST_INIT, (void (*)(void))keccak_init }, \535PROV_DISPATCH_FUNC_DIGEST_CONSTRUCT_END536537#define PROV_FUNC_SHAKE_DIGEST(name, bitlen, blksize, dgstsize, flags) \538PROV_FUNC_SHA3_DIGEST_COMMON(name, bitlen, blksize, dgstsize, flags), \539{ OSSL_FUNC_DIGEST_SQUEEZE, (void (*)(void))shake_squeeze }, \540{ OSSL_FUNC_DIGEST_INIT, (void (*)(void))keccak_init_params }, \541{ OSSL_FUNC_DIGEST_SET_CTX_PARAMS, (void (*)(void))shake_set_ctx_params }, \542{ OSSL_FUNC_DIGEST_SETTABLE_CTX_PARAMS, \543(void (*)(void))shake_settable_ctx_params }, \544{ OSSL_FUNC_DIGEST_GET_CTX_PARAMS, (void (*)(void))shake_get_ctx_params }, \545{ OSSL_FUNC_DIGEST_GETTABLE_CTX_PARAMS, \546(void (*)(void))shake_gettable_ctx_params }, \547PROV_DISPATCH_FUNC_DIGEST_CONSTRUCT_END548549static void keccak_freectx(void *vctx)550{551KECCAK1600_CTX *ctx = (KECCAK1600_CTX *)vctx;552553OPENSSL_clear_free(ctx, sizeof(*ctx));554}555556static void keccak_copyctx(void *voutctx, void *vinctx)557{558KECCAK1600_CTX *outctx = (KECCAK1600_CTX *)voutctx;559KECCAK1600_CTX *inctx = (KECCAK1600_CTX *)vinctx;560561*outctx = *inctx;562}563564static void *keccak_dupctx(void *ctx)565{566KECCAK1600_CTX *in = (KECCAK1600_CTX *)ctx;567KECCAK1600_CTX *ret = ossl_prov_is_running() ? OPENSSL_malloc(sizeof(*ret))568: NULL;569570if (ret != NULL)571*ret = *in;572return ret;573}574575static const OSSL_PARAM *shake_gettable_ctx_params(ossl_unused void *ctx,576ossl_unused void *provctx)577{578static const OSSL_PARAM known_shake_gettable_ctx_params[] = {579{ OSSL_DIGEST_PARAM_XOFLEN, OSSL_PARAM_UNSIGNED_INTEGER, NULL, 0, 0 },580{ OSSL_DIGEST_PARAM_SIZE, OSSL_PARAM_UNSIGNED_INTEGER, NULL, 0, 0 },581OSSL_PARAM_END582};583return known_shake_gettable_ctx_params;584}585586static int shake_get_ctx_params(void *vctx, OSSL_PARAM params[])587{588OSSL_PARAM *p;589KECCAK1600_CTX *ctx = (KECCAK1600_CTX *)vctx;590591if (ctx == NULL)592return 0;593if (ossl_param_is_empty(params))594return 1;595596p = OSSL_PARAM_locate(params, OSSL_DIGEST_PARAM_XOFLEN);597if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->md_size)) {598ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);599return 0;600}601/* Size is an alias of xoflen */602p = OSSL_PARAM_locate(params, OSSL_DIGEST_PARAM_SIZE);603if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->md_size)) {604ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);605return 0;606}607return 1;608}609610static const OSSL_PARAM *shake_settable_ctx_params(ossl_unused void *ctx,611ossl_unused void *provctx)612{613static const OSSL_PARAM known_shake_settable_ctx_params[] = {614{ OSSL_DIGEST_PARAM_XOFLEN, OSSL_PARAM_UNSIGNED_INTEGER, NULL, 0, 0 },615{ OSSL_DIGEST_PARAM_SIZE, OSSL_PARAM_UNSIGNED_INTEGER, NULL, 0, 0 },616OSSL_PARAM_END617};618619return known_shake_settable_ctx_params;620}621622static int shake_set_ctx_params(void *vctx, const OSSL_PARAM params[])623{624const OSSL_PARAM *p;625KECCAK1600_CTX *ctx = (KECCAK1600_CTX *)vctx;626627if (ctx == NULL)628return 0;629if (ossl_param_is_empty(params))630return 1;631632p = OSSL_PARAM_locate_const(params, OSSL_DIGEST_PARAM_XOFLEN);633if (p == NULL)634p = OSSL_PARAM_locate_const(params, OSSL_DIGEST_PARAM_SIZE);635636if (p != NULL && !OSSL_PARAM_get_size_t(p, &ctx->md_size)) {637ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);638return 0;639}640return 1;641}642643#define IMPLEMENT_SHA3_functions(bitlen) \644SHA3_newctx(sha3, SHA3_##bitlen, sha3_##bitlen, bitlen, '\x06') \645PROV_FUNC_SHA3_DIGEST(sha3_##bitlen, bitlen, \646SHA3_BLOCKSIZE(bitlen), SHA3_MDSIZE(bitlen), \647SHA3_FLAGS)648649#define IMPLEMENT_KECCAK_functions(bitlen) \650SHA3_newctx(keccak, KECCAK_##bitlen, keccak_##bitlen, bitlen, '\x01') \651PROV_FUNC_SHA3_DIGEST(keccak_##bitlen, bitlen, \652SHA3_BLOCKSIZE(bitlen), SHA3_MDSIZE(bitlen), \653SHA3_FLAGS)654655#define IMPLEMENT_SHAKE_functions(bitlen) \656SHAKE_newctx(shake, SHAKE_##bitlen, shake_##bitlen, bitlen, \6570 /* no default md length */, '\x1f') \658PROV_FUNC_SHAKE_DIGEST(shake_##bitlen, bitlen, \659SHA3_BLOCKSIZE(bitlen), 0, \660SHAKE_FLAGS)661662#define IMPLEMENT_KMAC_functions(bitlen) \663KMAC_newctx(keccak_kmac_##bitlen, bitlen, '\x04') \664PROV_FUNC_SHAKE_DIGEST(keccak_kmac_##bitlen, bitlen, \665SHA3_BLOCKSIZE(bitlen), KMAC_MDSIZE(bitlen), \666KMAC_FLAGS)667668/* ossl_sha3_224_functions */669IMPLEMENT_SHA3_functions(224)670/* ossl_sha3_256_functions */671IMPLEMENT_SHA3_functions(256)672/* ossl_sha3_384_functions */673IMPLEMENT_SHA3_functions(384)674/* ossl_sha3_512_functions */675IMPLEMENT_SHA3_functions(512)676/* ossl_keccak_224_functions */677IMPLEMENT_KECCAK_functions(224)678/* ossl_keccak_256_functions */679IMPLEMENT_KECCAK_functions(256)680/* ossl_keccak_384_functions */681IMPLEMENT_KECCAK_functions(384)682/* ossl_keccak_512_functions */683IMPLEMENT_KECCAK_functions(512)684/* ossl_shake_128_functions */685IMPLEMENT_SHAKE_functions(128)686/* ossl_shake_256_functions */687IMPLEMENT_SHAKE_functions(256)688/* ossl_keccak_kmac_128_functions */689IMPLEMENT_KMAC_functions(128)690/* ossl_keccak_kmac_256_functions */691IMPLEMENT_KMAC_functions(256)692693694