Path: blob/main/crypto/openssl/providers/implementations/kdfs/x942kdf.c
108679 views
/*1* Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved.2* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.3*4* Licensed under the Apache License 2.0 (the "License"). You may not use5* this file except in compliance with the License. You can obtain a copy6* in the file LICENSE in the source distribution or at7* https://www.openssl.org/source/license.html8*/910#include "internal/e_os.h"11#include <openssl/core_names.h>12#include <openssl/core_dispatch.h>13#include <openssl/err.h>14#include <openssl/evp.h>15#include <openssl/params.h>16#include <openssl/proverr.h>17#include "internal/packet.h"18#include "internal/der.h"19#include "internal/nelem.h"20#include "prov/provider_ctx.h"21#include "prov/providercommon.h"22#include "prov/implementations.h"23#include "prov/provider_util.h"24#include "prov/securitycheck.h"25#include "prov/der_wrap.h"2627#define X942KDF_MAX_INLEN (1 << 30)2829static OSSL_FUNC_kdf_newctx_fn x942kdf_new;30static OSSL_FUNC_kdf_dupctx_fn x942kdf_dup;31static OSSL_FUNC_kdf_freectx_fn x942kdf_free;32static OSSL_FUNC_kdf_reset_fn x942kdf_reset;33static OSSL_FUNC_kdf_derive_fn x942kdf_derive;34static OSSL_FUNC_kdf_settable_ctx_params_fn x942kdf_settable_ctx_params;35static OSSL_FUNC_kdf_set_ctx_params_fn x942kdf_set_ctx_params;36static OSSL_FUNC_kdf_gettable_ctx_params_fn x942kdf_gettable_ctx_params;37static OSSL_FUNC_kdf_get_ctx_params_fn x942kdf_get_ctx_params;3839typedef struct {40void *provctx;41PROV_DIGEST digest;42unsigned char *secret;43size_t secret_len;44unsigned char *acvpinfo;45size_t acvpinfo_len;46unsigned char *partyuinfo, *partyvinfo, *supp_pubinfo, *supp_privinfo;47size_t partyuinfo_len, partyvinfo_len, supp_pubinfo_len, supp_privinfo_len;48size_t dkm_len;49const unsigned char *cek_oid;50size_t cek_oid_len;51int use_keybits;52OSSL_FIPS_IND_DECLARE53} KDF_X942;5455/*56* A table of allowed wrapping algorithms, oids and the associated output57* lengths.58* NOTE: RC2wrap and camellia128_wrap have been removed as there are no59* corresponding ciphers for these operations.60*/61static const struct {62const char *name;63const unsigned char *oid;64size_t oid_len;65size_t keklen; /* size in bytes */66} kek_algs[] = {67{ "AES-128-WRAP", ossl_der_oid_id_aes128_wrap, DER_OID_SZ_id_aes128_wrap,6816 },69{ "AES-192-WRAP", ossl_der_oid_id_aes192_wrap, DER_OID_SZ_id_aes192_wrap,7024 },71{ "AES-256-WRAP", ossl_der_oid_id_aes256_wrap, DER_OID_SZ_id_aes256_wrap,7232 },73#ifndef FIPS_MODULE74{ "DES3-WRAP", ossl_der_oid_id_alg_CMS3DESwrap,75DER_OID_SZ_id_alg_CMS3DESwrap, 24 },76#endif77};7879static int find_alg_id(OSSL_LIB_CTX *libctx, const char *algname,80const char *propq, size_t *id)81{82int ret = 1;83size_t i;84EVP_CIPHER *cipher;8586cipher = EVP_CIPHER_fetch(libctx, algname, propq);87if (cipher != NULL) {88for (i = 0; i < OSSL_NELEM(kek_algs); i++) {89if (EVP_CIPHER_is_a(cipher, kek_algs[i].name)) {90*id = i;91goto end;92}93}94}95ret = 0;96ERR_raise(ERR_LIB_PROV, PROV_R_UNSUPPORTED_CEK_ALG);97end:98EVP_CIPHER_free(cipher);99return ret;100}101102static int DER_w_keyinfo(WPACKET *pkt,103const unsigned char *der_oid, size_t der_oidlen,104unsigned char **pcounter)105{106return ossl_DER_w_begin_sequence(pkt, -1)107/* Store the initial value of 1 into the counter */108&& ossl_DER_w_octet_string_uint32(pkt, -1, 1)109/* Remember where we stored the counter in the buffer */110&& (pcounter == NULL111|| (*pcounter = WPACKET_get_curr(pkt)) != NULL)112&& ossl_DER_w_precompiled(pkt, -1, der_oid, der_oidlen)113&& ossl_DER_w_end_sequence(pkt, -1);114}115116static int der_encode_sharedinfo(WPACKET *pkt, unsigned char *buf, size_t buflen,117const unsigned char *der_oid, size_t der_oidlen,118const unsigned char *acvp, size_t acvplen,119const unsigned char *partyu, size_t partyulen,120const unsigned char *partyv, size_t partyvlen,121const unsigned char *supp_pub, size_t supp_publen,122const unsigned char *supp_priv, size_t supp_privlen,123uint32_t keylen_bits, unsigned char **pcounter)124{125return (buf != NULL ? WPACKET_init_der(pkt, buf, buflen) : WPACKET_init_null_der(pkt))126&& ossl_DER_w_begin_sequence(pkt, -1)127&& (supp_priv == NULL128|| ossl_DER_w_octet_string(pkt, 3, supp_priv, supp_privlen))129&& (supp_pub == NULL130|| ossl_DER_w_octet_string(pkt, 2, supp_pub, supp_publen))131&& (keylen_bits == 0132|| ossl_DER_w_octet_string_uint32(pkt, 2, keylen_bits))133&& (partyv == NULL || ossl_DER_w_octet_string(pkt, 1, partyv, partyvlen))134&& (partyu == NULL || ossl_DER_w_octet_string(pkt, 0, partyu, partyulen))135&& (acvp == NULL || ossl_DER_w_precompiled(pkt, -1, acvp, acvplen))136&& DER_w_keyinfo(pkt, der_oid, der_oidlen, pcounter)137&& ossl_DER_w_end_sequence(pkt, -1)138&& WPACKET_finish(pkt);139}140141/*142* Encode the other info structure.143*144* The ANS X9.42-2003 standard uses OtherInfo:145*146* OtherInfo ::= SEQUENCE {147* keyInfo KeySpecificInfo,148* partyUInfo [0] OCTET STRING OPTIONAL,149* partyVInfo [1] OCTET STRING OPTIONAL,150* suppPubInfo [2] OCTET STRING OPTIONAL,151* suppPrivInfo [3] OCTET STRING OPTIONAL152* }153*154* KeySpecificInfo ::= SEQUENCE {155* algorithm OBJECT IDENTIFIER,156* counter OCTET STRING SIZE (4..4)157* }158*159* RFC2631 Section 2.1.2 Contains the following definition for OtherInfo160*161* OtherInfo ::= SEQUENCE {162* keyInfo KeySpecificInfo,163* partyAInfo [0] OCTET STRING OPTIONAL,164* suppPubInfo [2] OCTET STRING165* }166* Where suppPubInfo is the key length (in bits) (stored into 4 bytes)167*168* |keylen| is the length (in bytes) of the generated KEK. It is stored into169* suppPubInfo (in bits). It is ignored if the value is 0.170* |cek_oid| The oid of the key wrapping algorithm.171* |cek_oidlen| The length (in bytes) of the key wrapping algorithm oid,172* |acvp| is the optional blob of DER data representing one or more of the173* OtherInfo fields related to |partyu|, |partyv|, |supp_pub| and |supp_priv|.174* This field should normally be NULL. If |acvp| is non NULL then |partyu|,175* |partyv|, |supp_pub| and |supp_priv| should all be NULL.176* |acvp_len| is the |acvp| length (in bytes).177* |partyu| is the optional public info contributed by the initiator.178* It can be NULL. (It is also used as the ukm by CMS).179* |partyu_len| is the |partyu| length (in bytes).180* |partyv| is the optional public info contributed by the responder.181* It can be NULL.182* |partyv_len| is the |partyv| length (in bytes).183* |supp_pub| is the optional additional, mutually-known public information.184* It can be NULL. |keylen| should be 0 if this is not NULL.185* |supp_pub_len| is the |supp_pub| length (in bytes).186* |supp_priv| is the optional additional, mutually-known private information.187* It can be NULL.188* |supp_priv_len| is the |supp_priv| length (in bytes).189* |der| is the returned encoded data. It must be freed by the caller.190* |der_len| is the returned size of the encoded data.191* |out_ctr| returns a pointer to the counter data which is embedded inside the192* encoded data. This allows the counter bytes to be updated without193* re-encoding.194*195* Returns: 1 if successfully encoded, or 0 otherwise.196* Assumptions: |der|, |der_len| & |out_ctr| are not NULL.197*/198static int199x942_encode_otherinfo(size_t keylen,200const unsigned char *cek_oid, size_t cek_oid_len,201const unsigned char *acvp, size_t acvp_len,202const unsigned char *partyu, size_t partyu_len,203const unsigned char *partyv, size_t partyv_len,204const unsigned char *supp_pub, size_t supp_pub_len,205const unsigned char *supp_priv, size_t supp_priv_len,206unsigned char **der, size_t *der_len,207unsigned char **out_ctr)208{209int ret = 0;210unsigned char *pcounter = NULL, *der_buf = NULL;211size_t der_buflen = 0;212WPACKET pkt;213uint32_t keylen_bits;214215/* keylenbits must fit into 4 bytes */216if (keylen > 0xFFFFFF)217return 0;218keylen_bits = 8 * keylen;219220/* Calculate the size of the buffer */221if (!der_encode_sharedinfo(&pkt, NULL, 0, cek_oid, cek_oid_len,222acvp, acvp_len,223partyu, partyu_len, partyv, partyv_len,224supp_pub, supp_pub_len, supp_priv, supp_priv_len,225keylen_bits, NULL)226|| !WPACKET_get_total_written(&pkt, &der_buflen))227goto err;228WPACKET_cleanup(&pkt);229/* Alloc the buffer */230der_buf = OPENSSL_zalloc(der_buflen);231if (der_buf == NULL)232goto err;233/* Encode into the buffer */234if (!der_encode_sharedinfo(&pkt, der_buf, der_buflen, cek_oid, cek_oid_len,235acvp, acvp_len,236partyu, partyu_len, partyv, partyv_len,237supp_pub, supp_pub_len, supp_priv, supp_priv_len,238keylen_bits, &pcounter))239goto err;240/*241* Since we allocated the exact size required, the buffer should point to the242* start of the allocated buffer at this point.243*/244if (WPACKET_get_curr(&pkt) != der_buf)245goto err;246247/*248* The data for the DER encoded octet string of a 32 bit counter = 1249* should be 04 04 00 00 00 01250* So just check the header is correct and skip over it.251* This counter will be incremented in the kdf update loop.252*/253if (pcounter == NULL254|| pcounter[0] != 0x04255|| pcounter[1] != 0x04)256goto err;257*out_ctr = (pcounter + 2);258*der = der_buf;259*der_len = der_buflen;260ret = 1;261err:262WPACKET_cleanup(&pkt);263return ret;264}265266static int x942kdf_hash_kdm(const EVP_MD *kdf_md,267const unsigned char *z, size_t z_len,268const unsigned char *other, size_t other_len,269unsigned char *ctr,270unsigned char *derived_key, size_t derived_key_len)271{272int ret = 0, hlen;273size_t counter, out_len, len = derived_key_len;274unsigned char mac[EVP_MAX_MD_SIZE];275unsigned char *out = derived_key;276EVP_MD_CTX *ctx = NULL, *ctx_init = NULL;277278if (z_len > X942KDF_MAX_INLEN279|| other_len > X942KDF_MAX_INLEN280|| derived_key_len > X942KDF_MAX_INLEN281|| derived_key_len == 0) {282ERR_raise(ERR_LIB_PROV, PROV_R_BAD_LENGTH);283return 0;284}285286hlen = EVP_MD_get_size(kdf_md);287if (hlen <= 0)288return 0;289out_len = (size_t)hlen;290291ctx = EVP_MD_CTX_create();292ctx_init = EVP_MD_CTX_create();293if (ctx == NULL || ctx_init == NULL)294goto end;295296if (!EVP_DigestInit(ctx_init, kdf_md))297goto end;298299for (counter = 1;; counter++) {300/* updating the ctr modifies 4 bytes in the 'other' buffer */301ctr[0] = (unsigned char)((counter >> 24) & 0xff);302ctr[1] = (unsigned char)((counter >> 16) & 0xff);303ctr[2] = (unsigned char)((counter >> 8) & 0xff);304ctr[3] = (unsigned char)(counter & 0xff);305306if (!EVP_MD_CTX_copy_ex(ctx, ctx_init)307|| !EVP_DigestUpdate(ctx, z, z_len)308|| !EVP_DigestUpdate(ctx, other, other_len))309goto end;310if (len >= out_len) {311if (!EVP_DigestFinal_ex(ctx, out, NULL))312goto end;313out += out_len;314len -= out_len;315if (len == 0)316break;317} else {318if (!EVP_DigestFinal_ex(ctx, mac, NULL))319goto end;320memcpy(out, mac, len);321break;322}323}324ret = 1;325end:326EVP_MD_CTX_free(ctx);327EVP_MD_CTX_free(ctx_init);328OPENSSL_cleanse(mac, sizeof(mac));329return ret;330}331332static void *x942kdf_new(void *provctx)333{334KDF_X942 *ctx;335336if (!ossl_prov_is_running())337return NULL;338339ctx = OPENSSL_zalloc(sizeof(*ctx));340if (ctx == NULL)341return NULL;342343ctx->provctx = provctx;344OSSL_FIPS_IND_INIT(ctx)345ctx->use_keybits = 1;346return ctx;347}348349static void x942kdf_reset(void *vctx)350{351KDF_X942 *ctx = (KDF_X942 *)vctx;352void *provctx = ctx->provctx;353354ossl_prov_digest_reset(&ctx->digest);355OPENSSL_clear_free(ctx->secret, ctx->secret_len);356OPENSSL_clear_free(ctx->acvpinfo, ctx->acvpinfo_len);357OPENSSL_clear_free(ctx->partyuinfo, ctx->partyuinfo_len);358OPENSSL_clear_free(ctx->partyvinfo, ctx->partyvinfo_len);359OPENSSL_clear_free(ctx->supp_pubinfo, ctx->supp_pubinfo_len);360OPENSSL_clear_free(ctx->supp_privinfo, ctx->supp_privinfo_len);361memset(ctx, 0, sizeof(*ctx));362ctx->provctx = provctx;363ctx->use_keybits = 1;364}365366static void x942kdf_free(void *vctx)367{368KDF_X942 *ctx = (KDF_X942 *)vctx;369370if (ctx != NULL) {371x942kdf_reset(ctx);372OPENSSL_free(ctx);373}374}375376static void *x942kdf_dup(void *vctx)377{378const KDF_X942 *src = (const KDF_X942 *)vctx;379KDF_X942 *dest;380381dest = x942kdf_new(src->provctx);382if (dest != NULL) {383if (!ossl_prov_memdup(src->secret, src->secret_len,384&dest->secret, &dest->secret_len)385|| !ossl_prov_memdup(src->acvpinfo, src->acvpinfo_len,386&dest->acvpinfo, &dest->acvpinfo_len)387|| !ossl_prov_memdup(src->partyuinfo, src->partyuinfo_len,388&dest->partyuinfo, &dest->partyuinfo_len)389|| !ossl_prov_memdup(src->partyvinfo, src->partyvinfo_len,390&dest->partyvinfo, &dest->partyvinfo_len)391|| !ossl_prov_memdup(src->supp_pubinfo, src->supp_pubinfo_len,392&dest->supp_pubinfo,393&dest->supp_pubinfo_len)394|| !ossl_prov_memdup(src->supp_privinfo, src->supp_privinfo_len,395&dest->supp_privinfo,396&dest->supp_privinfo_len)397|| !ossl_prov_digest_copy(&dest->digest, &src->digest))398goto err;399dest->cek_oid = src->cek_oid;400dest->cek_oid_len = src->cek_oid_len;401dest->dkm_len = src->dkm_len;402dest->use_keybits = src->use_keybits;403OSSL_FIPS_IND_COPY(dest, src)404}405return dest;406407err:408x942kdf_free(dest);409return NULL;410}411412static int x942kdf_set_buffer(unsigned char **out, size_t *out_len,413const OSSL_PARAM *p)414{415if (p->data_size == 0 || p->data == NULL)416return 1;417418OPENSSL_free(*out);419*out = NULL;420return OSSL_PARAM_get_octet_string(p, (void **)out, 0, out_len);421}422423static size_t x942kdf_size(KDF_X942 *ctx)424{425int len;426const EVP_MD *md = ossl_prov_digest_md(&ctx->digest);427428if (md == NULL) {429ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST);430return 0;431}432len = EVP_MD_get_size(md);433return (len <= 0) ? 0 : (size_t)len;434}435436#ifdef FIPS_MODULE437static int fips_x942kdf_key_check_passed(KDF_X942 *ctx)438{439OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);440int key_approved = ossl_kdf_check_key_size(ctx->secret_len);441442if (!key_approved) {443if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE0,444libctx, "X942KDF", "Key size",445ossl_fips_config_x942kdf_key_check)) {446ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);447return 0;448}449}450return 1;451}452#endif453454static int x942kdf_derive(void *vctx, unsigned char *key, size_t keylen,455const OSSL_PARAM params[])456{457KDF_X942 *ctx = (KDF_X942 *)vctx;458const EVP_MD *md;459int ret = 0;460unsigned char *ctr;461unsigned char *der = NULL;462size_t der_len = 0;463464if (!ossl_prov_is_running() || !x942kdf_set_ctx_params(ctx, params))465return 0;466467/*468* These 2 options encode to the same field so only one of them should be469* active at once.470*/471if (ctx->use_keybits && ctx->supp_pubinfo != NULL) {472ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_PUBINFO);473return 0;474}475/*476* If the blob of acvp data is used then the individual info fields that it477* replaces should not also be defined.478*/479if (ctx->acvpinfo != NULL480&& (ctx->partyuinfo != NULL481|| ctx->partyvinfo != NULL482|| ctx->supp_pubinfo != NULL483|| ctx->supp_privinfo != NULL)) {484ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DATA);485return 0;486}487if (ctx->secret == NULL) {488ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_SECRET);489return 0;490}491md = ossl_prov_digest_md(&ctx->digest);492if (md == NULL) {493ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST);494return 0;495}496if (ctx->cek_oid == NULL || ctx->cek_oid_len == 0) {497ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CEK_ALG);498return 0;499}500if (ctx->partyuinfo != NULL && ctx->partyuinfo_len >= X942KDF_MAX_INLEN) {501/*502* Note the ukm length MUST be 512 bits if it is used.503* For backwards compatibility the old check is being done.504*/505ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_UKM_LENGTH);506return 0;507}508/* generate the otherinfo der */509if (!x942_encode_otherinfo(ctx->use_keybits ? ctx->dkm_len : 0,510ctx->cek_oid, ctx->cek_oid_len,511ctx->acvpinfo, ctx->acvpinfo_len,512ctx->partyuinfo, ctx->partyuinfo_len,513ctx->partyvinfo, ctx->partyvinfo_len,514ctx->supp_pubinfo, ctx->supp_pubinfo_len,515ctx->supp_privinfo, ctx->supp_privinfo_len,516&der, &der_len, &ctr)) {517ERR_raise(ERR_LIB_PROV, PROV_R_BAD_ENCODING);518return 0;519}520ret = x942kdf_hash_kdm(md, ctx->secret, ctx->secret_len,521der, der_len, ctr, key, keylen);522OPENSSL_free(der);523return ret;524}525526static int x942kdf_set_ctx_params(void *vctx, const OSSL_PARAM params[])527{528const OSSL_PARAM *p, *pq;529KDF_X942 *ctx = vctx;530OSSL_LIB_CTX *provctx = PROV_LIBCTX_OF(ctx->provctx);531const char *propq = NULL;532const EVP_MD *md;533size_t id;534535if (ossl_param_is_empty(params))536return 1;537538if (!OSSL_FIPS_IND_SET_CTX_PARAM(ctx, OSSL_FIPS_IND_SETTABLE0, params,539OSSL_KDF_PARAM_FIPS_KEY_CHECK))540return 0;541542if (OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_DIGEST) != NULL) {543if (!ossl_prov_digest_load_from_params(&ctx->digest, params, provctx))544return 0;545md = ossl_prov_digest_md(&ctx->digest);546if (EVP_MD_xof(md)) {547ERR_raise(ERR_LIB_PROV, PROV_R_XOF_DIGESTS_NOT_ALLOWED);548return 0;549}550}551552p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SECRET);553if (p == NULL)554p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_KEY);555if (p != NULL) {556if (!x942kdf_set_buffer(&ctx->secret, &ctx->secret_len, p))557return 0;558#ifdef FIPS_MODULE559if (!fips_x942kdf_key_check_passed(ctx))560return 0;561#endif562}563564p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_X942_ACVPINFO);565if (p != NULL566&& !x942kdf_set_buffer(&ctx->acvpinfo, &ctx->acvpinfo_len, p))567return 0;568569p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_X942_PARTYUINFO);570if (p == NULL)571p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_UKM);572if (p != NULL573&& !x942kdf_set_buffer(&ctx->partyuinfo, &ctx->partyuinfo_len, p))574return 0;575576p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_X942_PARTYVINFO);577if (p != NULL578&& !x942kdf_set_buffer(&ctx->partyvinfo, &ctx->partyvinfo_len, p))579return 0;580581p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_X942_USE_KEYBITS);582if (p != NULL && !OSSL_PARAM_get_int(p, &ctx->use_keybits))583return 0;584585p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_X942_SUPP_PUBINFO);586if (p != NULL) {587if (!x942kdf_set_buffer(&ctx->supp_pubinfo, &ctx->supp_pubinfo_len, p))588return 0;589ctx->use_keybits = 0;590}591592p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_X942_SUPP_PRIVINFO);593if (p != NULL594&& !x942kdf_set_buffer(&ctx->supp_privinfo, &ctx->supp_privinfo_len, p))595return 0;596597p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_CEK_ALG);598if (p != NULL) {599if (p->data_type != OSSL_PARAM_UTF8_STRING)600return 0;601pq = OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_PROPERTIES);602/*603* We already grab the properties during ossl_prov_digest_load_from_params()604* so there is no need to check the validity again..605*/606if (pq != NULL)607propq = p->data;608if (find_alg_id(provctx, p->data, propq, &id) == 0)609return 0;610ctx->cek_oid = kek_algs[id].oid;611ctx->cek_oid_len = kek_algs[id].oid_len;612ctx->dkm_len = kek_algs[id].keklen;613}614return 1;615}616617static const OSSL_PARAM *x942kdf_settable_ctx_params(ossl_unused void *ctx,618ossl_unused void *provctx)619{620static const OSSL_PARAM known_settable_ctx_params[] = {621OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0),622OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_DIGEST, NULL, 0),623OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SECRET, NULL, 0),624OSSL_PARAM_octet_string(OSSL_KDF_PARAM_KEY, NULL, 0),625OSSL_PARAM_octet_string(OSSL_KDF_PARAM_UKM, NULL, 0),626OSSL_PARAM_octet_string(OSSL_KDF_PARAM_X942_ACVPINFO, NULL, 0),627OSSL_PARAM_octet_string(OSSL_KDF_PARAM_X942_PARTYUINFO, NULL, 0),628OSSL_PARAM_octet_string(OSSL_KDF_PARAM_X942_PARTYVINFO, NULL, 0),629OSSL_PARAM_octet_string(OSSL_KDF_PARAM_X942_SUPP_PUBINFO, NULL, 0),630OSSL_PARAM_octet_string(OSSL_KDF_PARAM_X942_SUPP_PRIVINFO, NULL, 0),631OSSL_PARAM_int(OSSL_KDF_PARAM_X942_USE_KEYBITS, NULL),632OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_CEK_ALG, NULL, 0),633OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_KDF_PARAM_FIPS_KEY_CHECK)634OSSL_PARAM_END635};636return known_settable_ctx_params;637}638639static int x942kdf_get_ctx_params(void *vctx, OSSL_PARAM params[])640{641KDF_X942 *ctx = (KDF_X942 *)vctx;642OSSL_PARAM *p;643644p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE);645if (p != NULL && !OSSL_PARAM_set_size_t(p, x942kdf_size(ctx)))646return 0;647648if (!OSSL_FIPS_IND_GET_CTX_PARAM(ctx, params))649return 0;650return 1;651}652653static const OSSL_PARAM *x942kdf_gettable_ctx_params(ossl_unused void *ctx,654ossl_unused void *provctx)655{656static const OSSL_PARAM known_gettable_ctx_params[] = {657OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL),658OSSL_FIPS_IND_GETTABLE_CTX_PARAM()659OSSL_PARAM_END660};661return known_gettable_ctx_params;662}663664const OSSL_DISPATCH ossl_kdf_x942_kdf_functions[] = {665{ OSSL_FUNC_KDF_NEWCTX, (void (*)(void))x942kdf_new },666{ OSSL_FUNC_KDF_DUPCTX, (void (*)(void))x942kdf_dup },667{ OSSL_FUNC_KDF_FREECTX, (void (*)(void))x942kdf_free },668{ OSSL_FUNC_KDF_RESET, (void (*)(void))x942kdf_reset },669{ OSSL_FUNC_KDF_DERIVE, (void (*)(void))x942kdf_derive },670{ OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS,671(void (*)(void))x942kdf_settable_ctx_params },672{ OSSL_FUNC_KDF_SET_CTX_PARAMS, (void (*)(void))x942kdf_set_ctx_params },673{ OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS,674(void (*)(void))x942kdf_gettable_ctx_params },675{ OSSL_FUNC_KDF_GET_CTX_PARAMS, (void (*)(void))x942kdf_get_ctx_params },676OSSL_DISPATCH_END677};678679680