Path: blob/main/crypto/openssl/providers/implementations/exchange/kdf_exch.c
48383 views
/*1* Copyright 2020-2024 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 <openssl/crypto.h>10#include <openssl/kdf.h>11#include <openssl/core_dispatch.h>12#include <openssl/core_names.h>13#include <openssl/err.h>14#include <openssl/proverr.h>15#include <openssl/params.h>16#include "internal/numbers.h"17#include "prov/implementations.h"18#include "prov/provider_ctx.h"19#include "prov/kdfexchange.h"20#include "prov/providercommon.h"2122static OSSL_FUNC_keyexch_newctx_fn kdf_tls1_prf_newctx;23static OSSL_FUNC_keyexch_newctx_fn kdf_hkdf_newctx;24static OSSL_FUNC_keyexch_newctx_fn kdf_scrypt_newctx;25static OSSL_FUNC_keyexch_init_fn kdf_init;26static OSSL_FUNC_keyexch_derive_fn kdf_derive;27static OSSL_FUNC_keyexch_freectx_fn kdf_freectx;28static OSSL_FUNC_keyexch_dupctx_fn kdf_dupctx;29static OSSL_FUNC_keyexch_set_ctx_params_fn kdf_set_ctx_params;30static OSSL_FUNC_keyexch_get_ctx_params_fn kdf_get_ctx_params;31static OSSL_FUNC_keyexch_settable_ctx_params_fn kdf_tls1_prf_settable_ctx_params;32static OSSL_FUNC_keyexch_settable_ctx_params_fn kdf_hkdf_settable_ctx_params;33static OSSL_FUNC_keyexch_settable_ctx_params_fn kdf_scrypt_settable_ctx_params;34static OSSL_FUNC_keyexch_gettable_ctx_params_fn kdf_tls1_prf_gettable_ctx_params;35static OSSL_FUNC_keyexch_gettable_ctx_params_fn kdf_hkdf_gettable_ctx_params;36static OSSL_FUNC_keyexch_gettable_ctx_params_fn kdf_scrypt_gettable_ctx_params;3738typedef struct {39void *provctx;40EVP_KDF_CTX *kdfctx;41KDF_DATA *kdfdata;42} PROV_KDF_CTX;4344static void *kdf_newctx(const char *kdfname, void *provctx)45{46PROV_KDF_CTX *kdfctx;47EVP_KDF *kdf = NULL;4849if (!ossl_prov_is_running())50return NULL;5152kdfctx = OPENSSL_zalloc(sizeof(PROV_KDF_CTX));53if (kdfctx == NULL)54return NULL;5556kdfctx->provctx = provctx;5758kdf = EVP_KDF_fetch(PROV_LIBCTX_OF(provctx), kdfname, NULL);59if (kdf == NULL)60goto err;61kdfctx->kdfctx = EVP_KDF_CTX_new(kdf);62EVP_KDF_free(kdf);6364if (kdfctx->kdfctx == NULL)65goto err;6667return kdfctx;68err:69OPENSSL_free(kdfctx);70return NULL;71}7273#define KDF_NEWCTX(funcname, kdfname) \74static void *kdf_##funcname##_newctx(void *provctx) \75{ \76return kdf_newctx(kdfname, provctx); \77}7879KDF_NEWCTX(tls1_prf, "TLS1-PRF")80KDF_NEWCTX(hkdf, "HKDF")81KDF_NEWCTX(scrypt, "SCRYPT")8283static int kdf_init(void *vpkdfctx, void *vkdf, const OSSL_PARAM params[])84{85PROV_KDF_CTX *pkdfctx = (PROV_KDF_CTX *)vpkdfctx;8687if (!ossl_prov_is_running()88|| pkdfctx == NULL89|| vkdf == NULL90|| !ossl_kdf_data_up_ref(vkdf))91return 0;92pkdfctx->kdfdata = vkdf;9394return kdf_set_ctx_params(pkdfctx, params);95}9697static int kdf_derive(void *vpkdfctx, unsigned char *secret, size_t *secretlen,98size_t outlen)99{100PROV_KDF_CTX *pkdfctx = (PROV_KDF_CTX *)vpkdfctx;101size_t kdfsize;102int ret;103104if (!ossl_prov_is_running())105return 0;106107kdfsize = EVP_KDF_CTX_get_kdf_size(pkdfctx->kdfctx);108109if (secret == NULL) {110*secretlen = kdfsize;111return 1;112}113114if (kdfsize != SIZE_MAX) {115if (outlen < kdfsize) {116ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);117return 0;118}119outlen = kdfsize;120}121122ret = EVP_KDF_derive(pkdfctx->kdfctx, secret, outlen, NULL);123if (ret <= 0)124return 0;125126*secretlen = outlen;127return 1;128}129130static void kdf_freectx(void *vpkdfctx)131{132PROV_KDF_CTX *pkdfctx = (PROV_KDF_CTX *)vpkdfctx;133134EVP_KDF_CTX_free(pkdfctx->kdfctx);135ossl_kdf_data_free(pkdfctx->kdfdata);136137OPENSSL_free(pkdfctx);138}139140static void *kdf_dupctx(void *vpkdfctx)141{142PROV_KDF_CTX *srcctx = (PROV_KDF_CTX *)vpkdfctx;143PROV_KDF_CTX *dstctx;144145if (!ossl_prov_is_running())146return NULL;147148dstctx = OPENSSL_zalloc(sizeof(*srcctx));149if (dstctx == NULL)150return NULL;151152*dstctx = *srcctx;153154dstctx->kdfctx = EVP_KDF_CTX_dup(srcctx->kdfctx);155if (dstctx->kdfctx == NULL) {156OPENSSL_free(dstctx);157return NULL;158}159if (!ossl_kdf_data_up_ref(dstctx->kdfdata)) {160EVP_KDF_CTX_free(dstctx->kdfctx);161OPENSSL_free(dstctx);162return NULL;163}164165return dstctx;166}167168static int kdf_set_ctx_params(void *vpkdfctx, const OSSL_PARAM params[])169{170PROV_KDF_CTX *pkdfctx = (PROV_KDF_CTX *)vpkdfctx;171172return EVP_KDF_CTX_set_params(pkdfctx->kdfctx, params);173}174175static int kdf_get_ctx_params(void *vpkdfctx, OSSL_PARAM params[])176{177PROV_KDF_CTX *pkdfctx = (PROV_KDF_CTX *)vpkdfctx;178179return EVP_KDF_CTX_get_params(pkdfctx->kdfctx, params);180}181182static const OSSL_PARAM *kdf_settable_ctx_params(ossl_unused void *vpkdfctx,183void *provctx,184const char *kdfname)185{186EVP_KDF *kdf = EVP_KDF_fetch(PROV_LIBCTX_OF(provctx), kdfname,187NULL);188const OSSL_PARAM *params;189190if (kdf == NULL)191return NULL;192193params = EVP_KDF_settable_ctx_params(kdf);194EVP_KDF_free(kdf);195196return params;197}198199#define KDF_SETTABLE_CTX_PARAMS(funcname, kdfname) \200static const OSSL_PARAM *kdf_##funcname##_settable_ctx_params(void *vpkdfctx, \201void *provctx) \202{ \203return kdf_settable_ctx_params(vpkdfctx, provctx, kdfname); \204}205206KDF_SETTABLE_CTX_PARAMS(tls1_prf, "TLS1-PRF")207KDF_SETTABLE_CTX_PARAMS(hkdf, "HKDF")208KDF_SETTABLE_CTX_PARAMS(scrypt, "SCRYPT")209210static const OSSL_PARAM *kdf_gettable_ctx_params(ossl_unused void *vpkdfctx,211void *provctx,212const char *kdfname)213{214EVP_KDF *kdf = EVP_KDF_fetch(PROV_LIBCTX_OF(provctx), kdfname,215NULL);216const OSSL_PARAM *params;217218if (kdf == NULL)219return NULL;220221params = EVP_KDF_gettable_ctx_params(kdf);222EVP_KDF_free(kdf);223224return params;225}226227#define KDF_GETTABLE_CTX_PARAMS(funcname, kdfname) \228static const OSSL_PARAM *kdf_##funcname##_gettable_ctx_params(void *vpkdfctx, \229void *provctx) \230{ \231return kdf_gettable_ctx_params(vpkdfctx, provctx, kdfname); \232}233234KDF_GETTABLE_CTX_PARAMS(tls1_prf, "TLS1-PRF")235KDF_GETTABLE_CTX_PARAMS(hkdf, "HKDF")236KDF_GETTABLE_CTX_PARAMS(scrypt, "SCRYPT")237238#define KDF_KEYEXCH_FUNCTIONS(funcname) \239const OSSL_DISPATCH ossl_kdf_##funcname##_keyexch_functions[] = { \240{ OSSL_FUNC_KEYEXCH_NEWCTX, (void (*)(void))kdf_##funcname##_newctx }, \241{ OSSL_FUNC_KEYEXCH_INIT, (void (*)(void))kdf_init }, \242{ OSSL_FUNC_KEYEXCH_DERIVE, (void (*)(void))kdf_derive }, \243{ OSSL_FUNC_KEYEXCH_FREECTX, (void (*)(void))kdf_freectx }, \244{ OSSL_FUNC_KEYEXCH_DUPCTX, (void (*)(void))kdf_dupctx }, \245{ OSSL_FUNC_KEYEXCH_SET_CTX_PARAMS, (void (*)(void))kdf_set_ctx_params }, \246{ OSSL_FUNC_KEYEXCH_GET_CTX_PARAMS, (void (*)(void))kdf_get_ctx_params }, \247{ OSSL_FUNC_KEYEXCH_SETTABLE_CTX_PARAMS, \248(void (*)(void))kdf_##funcname##_settable_ctx_params }, \249{ OSSL_FUNC_KEYEXCH_GETTABLE_CTX_PARAMS, \250(void (*)(void))kdf_##funcname##_gettable_ctx_params }, \251OSSL_DISPATCH_END \252};253254KDF_KEYEXCH_FUNCTIONS(tls1_prf)255KDF_KEYEXCH_FUNCTIONS(hkdf)256KDF_KEYEXCH_FUNCTIONS(scrypt)257258259