Path: blob/main/crypto/openssl/providers/implementations/kdfs/x942kdf.c
48383 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) :126WPACKET_init_null_der(pkt))127&& ossl_DER_w_begin_sequence(pkt, -1)128&& (supp_priv == NULL129|| ossl_DER_w_octet_string(pkt, 3, supp_priv, supp_privlen))130&& (supp_pub == NULL131|| ossl_DER_w_octet_string(pkt, 2, supp_pub, supp_publen))132&& (keylen_bits == 0133|| ossl_DER_w_octet_string_uint32(pkt, 2, keylen_bits))134&& (partyv == NULL || ossl_DER_w_octet_string(pkt, 1, partyv, partyvlen))135&& (partyu == NULL || ossl_DER_w_octet_string(pkt, 0, partyu, partyulen))136&& (acvp == NULL || ossl_DER_w_precompiled(pkt, -1, acvp, acvplen))137&& DER_w_keyinfo(pkt, der_oid, der_oidlen, pcounter)138&& ossl_DER_w_end_sequence(pkt, -1)139&& WPACKET_finish(pkt);140}141142/*143* Encode the other info structure.144*145* The ANS X9.42-2003 standard uses OtherInfo:146*147* OtherInfo ::= SEQUENCE {148* keyInfo KeySpecificInfo,149* partyUInfo [0] OCTET STRING OPTIONAL,150* partyVInfo [1] OCTET STRING OPTIONAL,151* suppPubInfo [2] OCTET STRING OPTIONAL,152* suppPrivInfo [3] OCTET STRING OPTIONAL153* }154*155* KeySpecificInfo ::= SEQUENCE {156* algorithm OBJECT IDENTIFIER,157* counter OCTET STRING SIZE (4..4)158* }159*160* RFC2631 Section 2.1.2 Contains the following definition for OtherInfo161*162* OtherInfo ::= SEQUENCE {163* keyInfo KeySpecificInfo,164* partyAInfo [0] OCTET STRING OPTIONAL,165* suppPubInfo [2] OCTET STRING166* }167* Where suppPubInfo is the key length (in bits) (stored into 4 bytes)168*169* |keylen| is the length (in bytes) of the generated KEK. It is stored into170* suppPubInfo (in bits). It is ignored if the value is 0.171* |cek_oid| The oid of the key wrapping algorithm.172* |cek_oidlen| The length (in bytes) of the key wrapping algorithm oid,173* |acvp| is the optional blob of DER data representing one or more of the174* OtherInfo fields related to |partyu|, |partyv|, |supp_pub| and |supp_priv|.175* This field should normally be NULL. If |acvp| is non NULL then |partyu|,176* |partyv|, |supp_pub| and |supp_priv| should all be NULL.177* |acvp_len| is the |acvp| length (in bytes).178* |partyu| is the optional public info contributed by the initiator.179* It can be NULL. (It is also used as the ukm by CMS).180* |partyu_len| is the |partyu| length (in bytes).181* |partyv| is the optional public info contributed by the responder.182* It can be NULL.183* |partyv_len| is the |partyv| length (in bytes).184* |supp_pub| is the optional additional, mutually-known public information.185* It can be NULL. |keylen| should be 0 if this is not NULL.186* |supp_pub_len| is the |supp_pub| length (in bytes).187* |supp_priv| is the optional additional, mutually-known private information.188* It can be NULL.189* |supp_priv_len| is the |supp_priv| length (in bytes).190* |der| is the returned encoded data. It must be freed by the caller.191* |der_len| is the returned size of the encoded data.192* |out_ctr| returns a pointer to the counter data which is embedded inside the193* encoded data. This allows the counter bytes to be updated without194* re-encoding.195*196* Returns: 1 if successfully encoded, or 0 otherwise.197* Assumptions: |der|, |der_len| & |out_ctr| are not NULL.198*/199static int200x942_encode_otherinfo(size_t keylen,201const unsigned char *cek_oid, size_t cek_oid_len,202const unsigned char *acvp, size_t acvp_len,203const unsigned char *partyu, size_t partyu_len,204const unsigned char *partyv, size_t partyv_len,205const unsigned char *supp_pub, size_t supp_pub_len,206const unsigned char *supp_priv, size_t supp_priv_len,207unsigned char **der, size_t *der_len,208unsigned char **out_ctr)209{210int ret = 0;211unsigned char *pcounter = NULL, *der_buf = NULL;212size_t der_buflen = 0;213WPACKET pkt;214uint32_t keylen_bits;215216/* keylenbits must fit into 4 bytes */217if (keylen > 0xFFFFFF)218return 0;219keylen_bits = 8 * keylen;220221/* Calculate the size of the buffer */222if (!der_encode_sharedinfo(&pkt, NULL, 0, cek_oid, cek_oid_len,223acvp, acvp_len,224partyu, partyu_len, partyv, partyv_len,225supp_pub, supp_pub_len, supp_priv, supp_priv_len,226keylen_bits, NULL)227|| !WPACKET_get_total_written(&pkt, &der_buflen))228goto err;229WPACKET_cleanup(&pkt);230/* Alloc the buffer */231der_buf = OPENSSL_zalloc(der_buflen);232if (der_buf == NULL)233goto err;234/* Encode into the buffer */235if (!der_encode_sharedinfo(&pkt, der_buf, der_buflen, cek_oid, cek_oid_len,236acvp, acvp_len,237partyu, partyu_len, partyv, partyv_len,238supp_pub, supp_pub_len, supp_priv, supp_priv_len,239keylen_bits, &pcounter))240goto err;241/*242* Since we allocated the exact size required, the buffer should point to the243* start of the allocated buffer at this point.244*/245if (WPACKET_get_curr(&pkt) != der_buf)246goto err;247248/*249* The data for the DER encoded octet string of a 32 bit counter = 1250* should be 04 04 00 00 00 01251* So just check the header is correct and skip over it.252* This counter will be incremented in the kdf update loop.253*/254if (pcounter == NULL255|| pcounter[0] != 0x04256|| pcounter[1] != 0x04)257goto err;258*out_ctr = (pcounter + 2);259*der = der_buf;260*der_len = der_buflen;261ret = 1;262err:263WPACKET_cleanup(&pkt);264return ret;265}266267static int x942kdf_hash_kdm(const EVP_MD *kdf_md,268const unsigned char *z, size_t z_len,269const unsigned char *other, size_t other_len,270unsigned char *ctr,271unsigned char *derived_key, size_t derived_key_len)272{273int ret = 0, hlen;274size_t counter, out_len, len = derived_key_len;275unsigned char mac[EVP_MAX_MD_SIZE];276unsigned char *out = derived_key;277EVP_MD_CTX *ctx = NULL, *ctx_init = NULL;278279if (z_len > X942KDF_MAX_INLEN280|| other_len > X942KDF_MAX_INLEN281|| derived_key_len > X942KDF_MAX_INLEN282|| derived_key_len == 0) {283ERR_raise(ERR_LIB_PROV, PROV_R_BAD_LENGTH);284return 0;285}286287hlen = EVP_MD_get_size(kdf_md);288if (hlen <= 0)289return 0;290out_len = (size_t)hlen;291292ctx = EVP_MD_CTX_create();293ctx_init = EVP_MD_CTX_create();294if (ctx == NULL || ctx_init == NULL)295goto end;296297if (!EVP_DigestInit(ctx_init, kdf_md))298goto end;299300for (counter = 1;; counter++) {301/* updating the ctr modifies 4 bytes in the 'other' buffer */302ctr[0] = (unsigned char)((counter >> 24) & 0xff);303ctr[1] = (unsigned char)((counter >> 16) & 0xff);304ctr[2] = (unsigned char)((counter >> 8) & 0xff);305ctr[3] = (unsigned char)(counter & 0xff);306307if (!EVP_MD_CTX_copy_ex(ctx, ctx_init)308|| !EVP_DigestUpdate(ctx, z, z_len)309|| !EVP_DigestUpdate(ctx, other, other_len))310goto end;311if (len >= out_len) {312if (!EVP_DigestFinal_ex(ctx, out, NULL))313goto end;314out += out_len;315len -= out_len;316if (len == 0)317break;318} else {319if (!EVP_DigestFinal_ex(ctx, mac, NULL))320goto end;321memcpy(out, mac, len);322break;323}324}325ret = 1;326end:327EVP_MD_CTX_free(ctx);328EVP_MD_CTX_free(ctx_init);329OPENSSL_cleanse(mac, sizeof(mac));330return ret;331}332333static void *x942kdf_new(void *provctx)334{335KDF_X942 *ctx;336337if (!ossl_prov_is_running())338return NULL;339340ctx = OPENSSL_zalloc(sizeof(*ctx));341if (ctx == NULL)342return NULL;343344ctx->provctx = provctx;345OSSL_FIPS_IND_INIT(ctx)346ctx->use_keybits = 1;347return ctx;348}349350static void x942kdf_reset(void *vctx)351{352KDF_X942 *ctx = (KDF_X942 *)vctx;353void *provctx = ctx->provctx;354355ossl_prov_digest_reset(&ctx->digest);356OPENSSL_clear_free(ctx->secret, ctx->secret_len);357OPENSSL_clear_free(ctx->acvpinfo, ctx->acvpinfo_len);358OPENSSL_clear_free(ctx->partyuinfo, ctx->partyuinfo_len);359OPENSSL_clear_free(ctx->partyvinfo, ctx->partyvinfo_len);360OPENSSL_clear_free(ctx->supp_pubinfo, ctx->supp_pubinfo_len);361OPENSSL_clear_free(ctx->supp_privinfo, ctx->supp_privinfo_len);362memset(ctx, 0, sizeof(*ctx));363ctx->provctx = provctx;364ctx->use_keybits = 1;365}366367static void x942kdf_free(void *vctx)368{369KDF_X942 *ctx = (KDF_X942 *)vctx;370371if (ctx != NULL) {372x942kdf_reset(ctx);373OPENSSL_free(ctx);374}375}376377static void *x942kdf_dup(void *vctx)378{379const KDF_X942 *src = (const KDF_X942 *)vctx;380KDF_X942 *dest;381382dest = x942kdf_new(src->provctx);383if (dest != NULL) {384if (!ossl_prov_memdup(src->secret, src->secret_len,385&dest->secret , &dest->secret_len)386|| !ossl_prov_memdup(src->acvpinfo, src->acvpinfo_len,387&dest->acvpinfo , &dest->acvpinfo_len)388|| !ossl_prov_memdup(src->partyuinfo, src->partyuinfo_len,389&dest->partyuinfo , &dest->partyuinfo_len)390|| !ossl_prov_memdup(src->partyvinfo, src->partyvinfo_len,391&dest->partyvinfo , &dest->partyvinfo_len)392|| !ossl_prov_memdup(src->supp_pubinfo, src->supp_pubinfo_len,393&dest->supp_pubinfo,394&dest->supp_pubinfo_len)395|| !ossl_prov_memdup(src->supp_privinfo, src->supp_privinfo_len,396&dest->supp_privinfo,397&dest->supp_privinfo_len)398|| !ossl_prov_digest_copy(&dest->digest, &src->digest))399goto err;400dest->cek_oid = src->cek_oid;401dest->cek_oid_len = src->cek_oid_len;402dest->dkm_len = src->dkm_len;403dest->use_keybits = src->use_keybits;404OSSL_FIPS_IND_COPY(dest, src)405}406return dest;407408err:409x942kdf_free(dest);410return NULL;411}412413static int x942kdf_set_buffer(unsigned char **out, size_t *out_len,414const OSSL_PARAM *p)415{416if (p->data_size == 0 || p->data == NULL)417return 1;418419OPENSSL_free(*out);420*out = NULL;421return OSSL_PARAM_get_octet_string(p, (void **)out, 0, out_len);422}423424static size_t x942kdf_size(KDF_X942 *ctx)425{426int len;427const EVP_MD *md = ossl_prov_digest_md(&ctx->digest);428429if (md == NULL) {430ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST);431return 0;432}433len = EVP_MD_get_size(md);434return (len <= 0) ? 0 : (size_t)len;435}436437#ifdef FIPS_MODULE438static int fips_x942kdf_key_check_passed(KDF_X942 *ctx)439{440OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);441int key_approved = ossl_kdf_check_key_size(ctx->secret_len);442443if (!key_approved) {444if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE0,445libctx, "X942KDF", "Key size",446ossl_fips_config_x942kdf_key_check)) {447ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);448return 0;449}450}451return 1;452}453#endif454455static int x942kdf_derive(void *vctx, unsigned char *key, size_t keylen,456const OSSL_PARAM params[])457{458KDF_X942 *ctx = (KDF_X942 *)vctx;459const EVP_MD *md;460int ret = 0;461unsigned char *ctr;462unsigned char *der = NULL;463size_t der_len = 0;464465if (!ossl_prov_is_running() || !x942kdf_set_ctx_params(ctx, params))466return 0;467468/*469* These 2 options encode to the same field so only one of them should be470* active at once.471*/472if (ctx->use_keybits && ctx->supp_pubinfo != NULL) {473ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_PUBINFO);474return 0;475}476/*477* If the blob of acvp data is used then the individual info fields that it478* replaces should not also be defined.479*/480if (ctx->acvpinfo != NULL481&& (ctx->partyuinfo != NULL482|| ctx->partyvinfo != NULL483|| ctx->supp_pubinfo != NULL484|| ctx->supp_privinfo != NULL)) {485ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DATA);486return 0;487}488if (ctx->secret == NULL) {489ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_SECRET);490return 0;491}492md = ossl_prov_digest_md(&ctx->digest);493if (md == NULL) {494ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST);495return 0;496}497if (ctx->cek_oid == NULL || ctx->cek_oid_len == 0) {498ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CEK_ALG);499return 0;500}501if (ctx->partyuinfo != NULL && ctx->partyuinfo_len >= X942KDF_MAX_INLEN) {502/*503* Note the ukm length MUST be 512 bits if it is used.504* For backwards compatibility the old check is being done.505*/506ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_UKM_LENGTH);507return 0;508}509/* generate the otherinfo der */510if (!x942_encode_otherinfo(ctx->use_keybits ? ctx->dkm_len : 0,511ctx->cek_oid, ctx->cek_oid_len,512ctx->acvpinfo, ctx->acvpinfo_len,513ctx->partyuinfo, ctx->partyuinfo_len,514ctx->partyvinfo, ctx->partyvinfo_len,515ctx->supp_pubinfo, ctx->supp_pubinfo_len,516ctx->supp_privinfo, ctx->supp_privinfo_len,517&der, &der_len, &ctr)) {518ERR_raise(ERR_LIB_PROV, PROV_R_BAD_ENCODING);519return 0;520}521ret = x942kdf_hash_kdm(md, ctx->secret, ctx->secret_len,522der, der_len, ctr, key, keylen);523OPENSSL_free(der);524return ret;525}526527static int x942kdf_set_ctx_params(void *vctx, const OSSL_PARAM params[])528{529const OSSL_PARAM *p, *pq;530KDF_X942 *ctx = vctx;531OSSL_LIB_CTX *provctx = PROV_LIBCTX_OF(ctx->provctx);532const char *propq = NULL;533const EVP_MD *md;534size_t id;535536if (ossl_param_is_empty(params))537return 1;538539if (!OSSL_FIPS_IND_SET_CTX_PARAM(ctx, OSSL_FIPS_IND_SETTABLE0, params,540OSSL_KDF_PARAM_FIPS_KEY_CHECK))541return 0;542543if (OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_DIGEST) != NULL) {544if (!ossl_prov_digest_load_from_params(&ctx->digest, params, provctx))545return 0;546md = ossl_prov_digest_md(&ctx->digest);547if (EVP_MD_xof(md)) {548ERR_raise(ERR_LIB_PROV, PROV_R_XOF_DIGESTS_NOT_ALLOWED);549return 0;550}551}552553p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SECRET);554if (p == NULL)555p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_KEY);556if (p != NULL) {557if (!x942kdf_set_buffer(&ctx->secret, &ctx->secret_len, p))558return 0;559#ifdef FIPS_MODULE560if (!fips_x942kdf_key_check_passed(ctx))561return 0;562#endif563}564565p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_X942_ACVPINFO);566if (p != NULL567&& !x942kdf_set_buffer(&ctx->acvpinfo, &ctx->acvpinfo_len, p))568return 0;569570p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_X942_PARTYUINFO);571if (p == NULL)572p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_UKM);573if (p != NULL574&& !x942kdf_set_buffer(&ctx->partyuinfo, &ctx->partyuinfo_len, p))575return 0;576577p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_X942_PARTYVINFO);578if (p != NULL579&& !x942kdf_set_buffer(&ctx->partyvinfo, &ctx->partyvinfo_len, p))580return 0;581582p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_X942_USE_KEYBITS);583if (p != NULL && !OSSL_PARAM_get_int(p, &ctx->use_keybits))584return 0;585586p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_X942_SUPP_PUBINFO);587if (p != NULL) {588if (!x942kdf_set_buffer(&ctx->supp_pubinfo, &ctx->supp_pubinfo_len, p))589return 0;590ctx->use_keybits = 0;591}592593p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_X942_SUPP_PRIVINFO);594if (p != NULL595&& !x942kdf_set_buffer(&ctx->supp_privinfo, &ctx->supp_privinfo_len, p))596return 0;597598p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_CEK_ALG);599if (p != NULL) {600if (p->data_type != OSSL_PARAM_UTF8_STRING)601return 0;602pq = OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_PROPERTIES);603/*604* We already grab the properties during ossl_prov_digest_load_from_params()605* so there is no need to check the validity again..606*/607if (pq != NULL)608propq = p->data;609if (find_alg_id(provctx, p->data, propq, &id) == 0)610return 0;611ctx->cek_oid = kek_algs[id].oid;612ctx->cek_oid_len = kek_algs[id].oid_len;613ctx->dkm_len = kek_algs[id].keklen;614}615return 1;616}617618static const OSSL_PARAM *x942kdf_settable_ctx_params(ossl_unused void *ctx,619ossl_unused void *provctx)620{621static const OSSL_PARAM known_settable_ctx_params[] = {622OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0),623OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_DIGEST, NULL, 0),624OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SECRET, NULL, 0),625OSSL_PARAM_octet_string(OSSL_KDF_PARAM_KEY, NULL, 0),626OSSL_PARAM_octet_string(OSSL_KDF_PARAM_UKM, NULL, 0),627OSSL_PARAM_octet_string(OSSL_KDF_PARAM_X942_ACVPINFO, NULL, 0),628OSSL_PARAM_octet_string(OSSL_KDF_PARAM_X942_PARTYUINFO, NULL, 0),629OSSL_PARAM_octet_string(OSSL_KDF_PARAM_X942_PARTYVINFO, NULL, 0),630OSSL_PARAM_octet_string(OSSL_KDF_PARAM_X942_SUPP_PUBINFO, NULL, 0),631OSSL_PARAM_octet_string(OSSL_KDF_PARAM_X942_SUPP_PRIVINFO, NULL, 0),632OSSL_PARAM_int(OSSL_KDF_PARAM_X942_USE_KEYBITS, NULL),633OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_CEK_ALG, NULL, 0),634OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_KDF_PARAM_FIPS_KEY_CHECK)635OSSL_PARAM_END636};637return known_settable_ctx_params;638}639640static int x942kdf_get_ctx_params(void *vctx, OSSL_PARAM params[])641{642KDF_X942 *ctx = (KDF_X942 *)vctx;643OSSL_PARAM *p;644645p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE);646if (p != NULL && !OSSL_PARAM_set_size_t(p, x942kdf_size(ctx)))647return 0;648649if (!OSSL_FIPS_IND_GET_CTX_PARAM(ctx, params))650return 0;651return 1;652}653654static const OSSL_PARAM *x942kdf_gettable_ctx_params(ossl_unused void *ctx,655ossl_unused void *provctx)656{657static const OSSL_PARAM known_gettable_ctx_params[] = {658OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL),659OSSL_FIPS_IND_GETTABLE_CTX_PARAM()660OSSL_PARAM_END661};662return known_gettable_ctx_params;663}664665const OSSL_DISPATCH ossl_kdf_x942_kdf_functions[] = {666{ OSSL_FUNC_KDF_NEWCTX, (void(*)(void))x942kdf_new },667{ OSSL_FUNC_KDF_DUPCTX, (void(*)(void))x942kdf_dup },668{ OSSL_FUNC_KDF_FREECTX, (void(*)(void))x942kdf_free },669{ OSSL_FUNC_KDF_RESET, (void(*)(void))x942kdf_reset },670{ OSSL_FUNC_KDF_DERIVE, (void(*)(void))x942kdf_derive },671{ OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS,672(void(*)(void))x942kdf_settable_ctx_params },673{ OSSL_FUNC_KDF_SET_CTX_PARAMS, (void(*)(void))x942kdf_set_ctx_params },674{ OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS,675(void(*)(void))x942kdf_gettable_ctx_params },676{ OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))x942kdf_get_ctx_params },677OSSL_DISPATCH_END678};679680681