/src/openssl30/providers/implementations/kdfs/kbkdf.c
| Line | Count | Source (jump to first uncovered line) | 
| 1 |  | /* | 
| 2 |  |  * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. | 
| 3 |  |  * Copyright 2019 Red Hat, Inc. | 
| 4 |  |  * | 
| 5 |  |  * Licensed under the Apache License 2.0 (the "License").  You may not use | 
| 6 |  |  * this file except in compliance with the License.  You can obtain a copy | 
| 7 |  |  * in the file LICENSE in the source distribution or at | 
| 8 |  |  * https://www.openssl.org/source/license.html | 
| 9 |  |  */ | 
| 10 |  |  | 
| 11 |  | /* | 
| 12 |  |  * This implements https://csrc.nist.gov/publications/detail/sp/800-108/final | 
| 13 |  |  * section 5.1 ("counter mode") and section 5.2 ("feedback mode") in both HMAC | 
| 14 |  |  * and CMAC.  That document does not name the KDFs it defines; the name is | 
| 15 |  |  * derived from | 
| 16 |  |  * https://csrc.nist.gov/Projects/Cryptographic-Algorithm-Validation-Program/Key-Derivation | 
| 17 |  |  * | 
| 18 |  |  * Note that section 5.3 ("double-pipeline mode") is not implemented, though | 
| 19 |  |  * it would be possible to do so in the future. | 
| 20 |  |  * | 
| 21 |  |  * These versions all assume the counter is used.  It would be relatively | 
| 22 |  |  * straightforward to expose a configuration handle should the need arise. | 
| 23 |  |  * | 
| 24 |  |  * Variable names attempt to match those of SP800-108. | 
| 25 |  |  */ | 
| 26 |  |  | 
| 27 |  | #include <stdarg.h> | 
| 28 |  | #include <stdlib.h> | 
| 29 |  | #include <string.h> | 
| 30 |  |  | 
| 31 |  | #include <openssl/core_names.h> | 
| 32 |  | #include <openssl/evp.h> | 
| 33 |  | #include <openssl/hmac.h> | 
| 34 |  | #include <openssl/kdf.h> | 
| 35 |  | #include <openssl/params.h> | 
| 36 |  | #include <openssl/proverr.h> | 
| 37 |  |  | 
| 38 |  | #include "internal/cryptlib.h" | 
| 39 |  | #include "crypto/evp.h" | 
| 40 |  | #include "internal/numbers.h" | 
| 41 |  | #include "internal/endian.h" | 
| 42 |  | #include "prov/implementations.h" | 
| 43 |  | #include "prov/provider_ctx.h" | 
| 44 |  | #include "prov/provider_util.h" | 
| 45 |  | #include "prov/providercommon.h" | 
| 46 |  |  | 
| 47 |  | #include "e_os.h" | 
| 48 |  |  | 
| 49 | 0 | #define ossl_min(a, b) ((a) < (b)) ? (a) : (b) | 
| 50 |  |  | 
| 51 |  | typedef enum { | 
| 52 |  |     COUNTER = 0, | 
| 53 |  |     FEEDBACK | 
| 54 |  | } kbkdf_mode; | 
| 55 |  |  | 
| 56 |  | /* Our context structure. */ | 
| 57 |  | typedef struct { | 
| 58 |  |     void *provctx; | 
| 59 |  |     kbkdf_mode mode; | 
| 60 |  |     EVP_MAC_CTX *ctx_init; | 
| 61 |  |  | 
| 62 |  |     /* Names are lowercased versions of those found in SP800-108. */ | 
| 63 |  |     unsigned char *ki; | 
| 64 |  |     size_t ki_len; | 
| 65 |  |     unsigned char *label; | 
| 66 |  |     size_t label_len; | 
| 67 |  |     unsigned char *context; | 
| 68 |  |     size_t context_len; | 
| 69 |  |     unsigned char *iv; | 
| 70 |  |     size_t iv_len; | 
| 71 |  |     int use_l; | 
| 72 |  |     int use_separator; | 
| 73 |  | } KBKDF; | 
| 74 |  |  | 
| 75 |  | /* Definitions needed for typechecking. */ | 
| 76 |  | static OSSL_FUNC_kdf_newctx_fn kbkdf_new; | 
| 77 |  | static OSSL_FUNC_kdf_freectx_fn kbkdf_free; | 
| 78 |  | static OSSL_FUNC_kdf_reset_fn kbkdf_reset; | 
| 79 |  | static OSSL_FUNC_kdf_derive_fn kbkdf_derive; | 
| 80 |  | static OSSL_FUNC_kdf_settable_ctx_params_fn kbkdf_settable_ctx_params; | 
| 81 |  | static OSSL_FUNC_kdf_set_ctx_params_fn kbkdf_set_ctx_params; | 
| 82 |  | static OSSL_FUNC_kdf_gettable_ctx_params_fn kbkdf_gettable_ctx_params; | 
| 83 |  | static OSSL_FUNC_kdf_get_ctx_params_fn kbkdf_get_ctx_params; | 
| 84 |  |  | 
| 85 |  | /* Not all platforms have htobe32(). */ | 
| 86 |  | static uint32_t be32(uint32_t host) | 
| 87 | 0 | { | 
| 88 | 0 |     uint32_t big = 0; | 
| 89 | 0 |     DECLARE_IS_ENDIAN; | 
| 90 |  | 
 | 
| 91 | 0 |     if (!IS_LITTLE_ENDIAN) | 
| 92 | 0 |         return host; | 
| 93 |  |  | 
| 94 | 0 |     big |= (host & 0xff000000) >> 24; | 
| 95 | 0 |     big |= (host & 0x00ff0000) >> 8; | 
| 96 | 0 |     big |= (host & 0x0000ff00) << 8; | 
| 97 | 0 |     big |= (host & 0x000000ff) << 24; | 
| 98 | 0 |     return big; | 
| 99 | 0 | } | 
| 100 |  |  | 
| 101 |  | static void init(KBKDF *ctx) | 
| 102 | 0 | { | 
| 103 | 0 |     ctx->use_l = 1; | 
| 104 | 0 |     ctx->use_separator = 1; | 
| 105 | 0 | } | 
| 106 |  |  | 
| 107 |  | static void *kbkdf_new(void *provctx) | 
| 108 | 0 | { | 
| 109 | 0 |     KBKDF *ctx; | 
| 110 |  | 
 | 
| 111 | 0 |     if (!ossl_prov_is_running()) | 
| 112 | 0 |         return NULL; | 
| 113 |  |  | 
| 114 | 0 |     ctx = OPENSSL_zalloc(sizeof(*ctx)); | 
| 115 | 0 |     if (ctx == NULL) { | 
| 116 | 0 |         ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); | 
| 117 | 0 |         return NULL; | 
| 118 | 0 |     } | 
| 119 |  |  | 
| 120 | 0 |     ctx->provctx = provctx; | 
| 121 | 0 |     init(ctx); | 
| 122 | 0 |     return ctx; | 
| 123 | 0 | } | 
| 124 |  |  | 
| 125 |  | static void kbkdf_free(void *vctx) | 
| 126 | 0 | { | 
| 127 | 0 |     KBKDF *ctx = (KBKDF *)vctx; | 
| 128 |  | 
 | 
| 129 | 0 |     if (ctx != NULL) { | 
| 130 | 0 |         kbkdf_reset(ctx); | 
| 131 | 0 |         OPENSSL_free(ctx); | 
| 132 | 0 |     } | 
| 133 | 0 | } | 
| 134 |  |  | 
| 135 |  | static void kbkdf_reset(void *vctx) | 
| 136 | 0 | { | 
| 137 | 0 |     KBKDF *ctx = (KBKDF *)vctx; | 
| 138 | 0 |     void *provctx = ctx->provctx; | 
| 139 |  | 
 | 
| 140 | 0 |     EVP_MAC_CTX_free(ctx->ctx_init); | 
| 141 | 0 |     OPENSSL_clear_free(ctx->context, ctx->context_len); | 
| 142 | 0 |     OPENSSL_clear_free(ctx->label, ctx->label_len); | 
| 143 | 0 |     OPENSSL_clear_free(ctx->ki, ctx->ki_len); | 
| 144 | 0 |     OPENSSL_clear_free(ctx->iv, ctx->iv_len); | 
| 145 | 0 |     memset(ctx, 0, sizeof(*ctx)); | 
| 146 | 0 |     ctx->provctx = provctx; | 
| 147 | 0 |     init(ctx); | 
| 148 | 0 | } | 
| 149 |  |  | 
| 150 |  | /* SP800-108 section 5.1 or section 5.2 depending on mode. */ | 
| 151 |  | static int derive(EVP_MAC_CTX *ctx_init, kbkdf_mode mode, unsigned char *iv, | 
| 152 |  |                   size_t iv_len, unsigned char *label, size_t label_len, | 
| 153 |  |                   unsigned char *context, size_t context_len, | 
| 154 |  |                   unsigned char *k_i, size_t h, uint32_t l, int has_separator, | 
| 155 |  |                   unsigned char *ko, size_t ko_len) | 
| 156 | 0 | { | 
| 157 | 0 |     int ret = 0; | 
| 158 | 0 |     EVP_MAC_CTX *ctx = NULL; | 
| 159 | 0 |     size_t written = 0, to_write, k_i_len = iv_len; | 
| 160 | 0 |     const unsigned char zero = 0; | 
| 161 | 0 |     uint32_t counter, i; | 
| 162 |  |     /* | 
| 163 |  |      * From SP800-108: | 
| 164 |  |      * The fixed input data is a concatenation of a Label, | 
| 165 |  |      * a separation indicator 0x00, the Context, and L. | 
| 166 |  |      * One or more of these fixed input data fields may be omitted. | 
| 167 |  |      * | 
| 168 |  |      * has_separator == 0 means that the separator is omitted. | 
| 169 |  |      * Passing a value of l == 0 means that L is omitted. | 
| 170 |  |      * The Context and L are omitted automatically if a NULL buffer is passed. | 
| 171 |  |      */ | 
| 172 | 0 |     int has_l = (l != 0); | 
| 173 |  |  | 
| 174 |  |     /* Setup K(0) for feedback mode. */ | 
| 175 | 0 |     if (iv_len > 0) | 
| 176 | 0 |         memcpy(k_i, iv, iv_len); | 
| 177 |  | 
 | 
| 178 | 0 |     for (counter = 1; written < ko_len; counter++) { | 
| 179 | 0 |         i = be32(counter); | 
| 180 |  | 
 | 
| 181 | 0 |         ctx = EVP_MAC_CTX_dup(ctx_init); | 
| 182 | 0 |         if (ctx == NULL) | 
| 183 | 0 |             goto done; | 
| 184 |  |  | 
| 185 |  |         /* Perform feedback, if appropriate. */ | 
| 186 | 0 |         if (mode == FEEDBACK && !EVP_MAC_update(ctx, k_i, k_i_len)) | 
| 187 | 0 |             goto done; | 
| 188 |  |  | 
| 189 | 0 |         if (!EVP_MAC_update(ctx, (unsigned char *)&i, 4) | 
| 190 | 0 |             || !EVP_MAC_update(ctx, label, label_len) | 
| 191 | 0 |             || (has_separator && !EVP_MAC_update(ctx, &zero, 1)) | 
| 192 | 0 |             || !EVP_MAC_update(ctx, context, context_len) | 
| 193 | 0 |             || (has_l && !EVP_MAC_update(ctx, (unsigned char *)&l, 4)) | 
| 194 | 0 |             || !EVP_MAC_final(ctx, k_i, NULL, h)) | 
| 195 | 0 |             goto done; | 
| 196 |  |  | 
| 197 | 0 |         to_write = ko_len - written; | 
| 198 | 0 |         memcpy(ko + written, k_i, ossl_min(to_write, h)); | 
| 199 | 0 |         written += h; | 
| 200 |  | 
 | 
| 201 | 0 |         k_i_len = h; | 
| 202 | 0 |         EVP_MAC_CTX_free(ctx); | 
| 203 | 0 |         ctx = NULL; | 
| 204 | 0 |     } | 
| 205 |  |  | 
| 206 | 0 |     ret = 1; | 
| 207 | 0 | done: | 
| 208 | 0 |     EVP_MAC_CTX_free(ctx); | 
| 209 | 0 |     return ret; | 
| 210 | 0 | } | 
| 211 |  |  | 
| 212 |  | static int kbkdf_derive(void *vctx, unsigned char *key, size_t keylen, | 
| 213 |  |                         const OSSL_PARAM params[]) | 
| 214 | 0 | { | 
| 215 | 0 |     KBKDF *ctx = (KBKDF *)vctx; | 
| 216 | 0 |     int ret = 0; | 
| 217 | 0 |     unsigned char *k_i = NULL; | 
| 218 | 0 |     uint32_t l = 0; | 
| 219 | 0 |     size_t h = 0; | 
| 220 |  | 
 | 
| 221 | 0 |     if (!ossl_prov_is_running() || !kbkdf_set_ctx_params(ctx, params)) | 
| 222 | 0 |         return 0; | 
| 223 |  |  | 
| 224 |  |     /* label, context, and iv are permitted to be empty.  Check everything | 
| 225 |  |      * else. */ | 
| 226 | 0 |     if (ctx->ctx_init == NULL) { | 
| 227 | 0 |         if (ctx->ki_len == 0 || ctx->ki == NULL) { | 
| 228 | 0 |             ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET); | 
| 229 | 0 |             return 0; | 
| 230 | 0 |         } | 
| 231 |  |         /* Could either be missing MAC or missing message digest or missing | 
| 232 |  |          * cipher - arbitrarily, I pick this one. */ | 
| 233 | 0 |         ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MAC); | 
| 234 | 0 |         return 0; | 
| 235 | 0 |     } | 
| 236 |  |  | 
| 237 |  |     /* Fail if the output length is zero */ | 
| 238 | 0 |     if (keylen == 0) { | 
| 239 | 0 |         ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); | 
| 240 | 0 |         return 0; | 
| 241 | 0 |     } | 
| 242 |  |  | 
| 243 | 0 |     h = EVP_MAC_CTX_get_mac_size(ctx->ctx_init); | 
| 244 | 0 |     if (h == 0) | 
| 245 | 0 |         goto done; | 
| 246 | 0 |     if (ctx->iv_len != 0 && ctx->iv_len != h) { | 
| 247 | 0 |         ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SEED_LENGTH); | 
| 248 | 0 |         goto done; | 
| 249 | 0 |     } | 
| 250 |  |  | 
| 251 | 0 |     if (ctx->use_l != 0) | 
| 252 | 0 |         l = be32(keylen * 8); | 
| 253 |  | 
 | 
| 254 | 0 |     k_i = OPENSSL_zalloc(h); | 
| 255 | 0 |     if (k_i == NULL) | 
| 256 | 0 |         goto done; | 
| 257 |  |  | 
| 258 | 0 |     ret = derive(ctx->ctx_init, ctx->mode, ctx->iv, ctx->iv_len, ctx->label, | 
| 259 | 0 |                  ctx->label_len, ctx->context, ctx->context_len, k_i, h, l, | 
| 260 | 0 |                  ctx->use_separator, key, keylen); | 
| 261 | 0 | done: | 
| 262 | 0 |     if (ret != 1) | 
| 263 | 0 |         OPENSSL_cleanse(key, keylen); | 
| 264 | 0 |     OPENSSL_clear_free(k_i, h); | 
| 265 | 0 |     return ret; | 
| 266 | 0 | } | 
| 267 |  |  | 
| 268 |  | static int kbkdf_set_buffer(unsigned char **out, size_t *out_len, | 
| 269 |  |                             const OSSL_PARAM *p) | 
| 270 | 0 | { | 
| 271 | 0 |     if (p->data == NULL || p->data_size == 0) | 
| 272 | 0 |         return 1; | 
| 273 |  |  | 
| 274 | 0 |     OPENSSL_clear_free(*out, *out_len); | 
| 275 | 0 |     *out = NULL; | 
| 276 | 0 |     return OSSL_PARAM_get_octet_string(p, (void **)out, 0, out_len); | 
| 277 | 0 | } | 
| 278 |  |  | 
| 279 |  | static int kbkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[]) | 
| 280 | 0 | { | 
| 281 | 0 |     KBKDF *ctx = (KBKDF *)vctx; | 
| 282 | 0 |     OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx); | 
| 283 | 0 |     const OSSL_PARAM *p; | 
| 284 |  | 
 | 
| 285 | 0 |     if (params == NULL) | 
| 286 | 0 |         return 1; | 
| 287 |  |  | 
| 288 | 0 |     if (!ossl_prov_macctx_load_from_params(&ctx->ctx_init, params, NULL, | 
| 289 | 0 |                                            NULL, NULL, libctx)) | 
| 290 | 0 |         return 0; | 
| 291 | 0 |     else if (ctx->ctx_init != NULL | 
| 292 | 0 |              && !EVP_MAC_is_a(EVP_MAC_CTX_get0_mac(ctx->ctx_init), | 
| 293 | 0 |                               OSSL_MAC_NAME_HMAC) | 
| 294 | 0 |              && !EVP_MAC_is_a(EVP_MAC_CTX_get0_mac(ctx->ctx_init), | 
| 295 | 0 |                               OSSL_MAC_NAME_CMAC)) { | 
| 296 | 0 |         ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_MAC); | 
| 297 | 0 |         return 0; | 
| 298 | 0 |     } | 
| 299 |  |  | 
| 300 | 0 |     p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_MODE); | 
| 301 | 0 |     if (p != NULL | 
| 302 | 0 |         && OPENSSL_strncasecmp("counter", p->data, p->data_size) == 0) { | 
| 303 | 0 |         ctx->mode = COUNTER; | 
| 304 | 0 |     } else if (p != NULL | 
| 305 | 0 |                && OPENSSL_strncasecmp("feedback", p->data, p->data_size) == 0) { | 
| 306 | 0 |         ctx->mode = FEEDBACK; | 
| 307 | 0 |     } else if (p != NULL) { | 
| 308 | 0 |         ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_MODE); | 
| 309 | 0 |         return 0; | 
| 310 | 0 |     } | 
| 311 |  |  | 
| 312 | 0 |     p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_KEY); | 
| 313 | 0 |     if (p != NULL && !kbkdf_set_buffer(&ctx->ki, &ctx->ki_len, p)) | 
| 314 | 0 |         return 0; | 
| 315 |  |  | 
| 316 | 0 |     p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SALT); | 
| 317 | 0 |     if (p != NULL && !kbkdf_set_buffer(&ctx->label, &ctx->label_len, p)) | 
| 318 | 0 |         return 0; | 
| 319 |  |  | 
| 320 | 0 |     p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_INFO); | 
| 321 | 0 |     if (p != NULL && !kbkdf_set_buffer(&ctx->context, &ctx->context_len, p)) | 
| 322 | 0 |         return 0; | 
| 323 |  |  | 
| 324 | 0 |     p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SEED); | 
| 325 | 0 |     if (p != NULL && !kbkdf_set_buffer(&ctx->iv, &ctx->iv_len, p)) | 
| 326 | 0 |         return 0; | 
| 327 |  |  | 
| 328 | 0 |     p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_KBKDF_USE_L); | 
| 329 | 0 |     if (p != NULL && !OSSL_PARAM_get_int(p, &ctx->use_l)) | 
| 330 | 0 |         return 0; | 
| 331 |  |  | 
| 332 | 0 |     p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_KBKDF_USE_SEPARATOR); | 
| 333 | 0 |     if (p != NULL && !OSSL_PARAM_get_int(p, &ctx->use_separator)) | 
| 334 | 0 |         return 0; | 
| 335 |  |  | 
| 336 |  |     /* Set up digest context, if we can. */ | 
| 337 | 0 |     if (ctx->ctx_init != NULL && ctx->ki_len != 0 | 
| 338 | 0 |             && !EVP_MAC_init(ctx->ctx_init, ctx->ki, ctx->ki_len, NULL)) | 
| 339 | 0 |             return 0; | 
| 340 | 0 |     return 1; | 
| 341 | 0 | } | 
| 342 |  |  | 
| 343 |  | static const OSSL_PARAM *kbkdf_settable_ctx_params(ossl_unused void *ctx, | 
| 344 |  |                                                    ossl_unused void *provctx) | 
| 345 | 0 | { | 
| 346 | 0 |     static const OSSL_PARAM known_settable_ctx_params[] = { | 
| 347 | 0 |         OSSL_PARAM_octet_string(OSSL_KDF_PARAM_INFO, NULL, 0), | 
| 348 | 0 |         OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SALT, NULL, 0), | 
| 349 | 0 |         OSSL_PARAM_octet_string(OSSL_KDF_PARAM_KEY, NULL, 0), | 
| 350 | 0 |         OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SEED, NULL, 0), | 
| 351 | 0 |         OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_DIGEST, NULL, 0), | 
| 352 | 0 |         OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_CIPHER, NULL, 0), | 
| 353 | 0 |         OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_MAC, NULL, 0), | 
| 354 | 0 |         OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_MODE, NULL, 0), | 
| 355 | 0 |         OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0), | 
| 356 | 0 |         OSSL_PARAM_int(OSSL_KDF_PARAM_KBKDF_USE_L, NULL), | 
| 357 | 0 |         OSSL_PARAM_int(OSSL_KDF_PARAM_KBKDF_USE_SEPARATOR, NULL), | 
| 358 | 0 |         OSSL_PARAM_END, | 
| 359 | 0 |     }; | 
| 360 | 0 |     return known_settable_ctx_params; | 
| 361 | 0 | } | 
| 362 |  |  | 
| 363 |  | static int kbkdf_get_ctx_params(void *vctx, OSSL_PARAM params[]) | 
| 364 | 0 | { | 
| 365 | 0 |     OSSL_PARAM *p; | 
| 366 |  | 
 | 
| 367 | 0 |     p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE); | 
| 368 | 0 |     if (p == NULL) | 
| 369 | 0 |         return -2; | 
| 370 |  |  | 
| 371 |  |     /* KBKDF can produce results as large as you like. */ | 
| 372 | 0 |     return OSSL_PARAM_set_size_t(p, SIZE_MAX); | 
| 373 | 0 | } | 
| 374 |  |  | 
| 375 |  | static const OSSL_PARAM *kbkdf_gettable_ctx_params(ossl_unused void *ctx, | 
| 376 |  |                                                    ossl_unused void *provctx) | 
| 377 | 0 | { | 
| 378 | 0 |     static const OSSL_PARAM known_gettable_ctx_params[] = | 
| 379 | 0 |         { OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL), OSSL_PARAM_END }; | 
| 380 | 0 |     return known_gettable_ctx_params; | 
| 381 | 0 | } | 
| 382 |  |  | 
| 383 |  | const OSSL_DISPATCH ossl_kdf_kbkdf_functions[] = { | 
| 384 |  |     { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))kbkdf_new }, | 
| 385 |  |     { OSSL_FUNC_KDF_FREECTX, (void(*)(void))kbkdf_free }, | 
| 386 |  |     { OSSL_FUNC_KDF_RESET, (void(*)(void))kbkdf_reset }, | 
| 387 |  |     { OSSL_FUNC_KDF_DERIVE, (void(*)(void))kbkdf_derive }, | 
| 388 |  |     { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS, | 
| 389 |  |       (void(*)(void))kbkdf_settable_ctx_params }, | 
| 390 |  |     { OSSL_FUNC_KDF_SET_CTX_PARAMS, (void(*)(void))kbkdf_set_ctx_params }, | 
| 391 |  |     { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS, | 
| 392 |  |       (void(*)(void))kbkdf_gettable_ctx_params }, | 
| 393 |  |     { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))kbkdf_get_ctx_params }, | 
| 394 |  |     { 0, NULL }, | 
| 395 |  | }; |