diff --git a/openvpn/openssl/crypto/tls1prf.hpp b/openvpn/openssl/crypto/tls1prf.hpp index b6be0219a..f40e9eeaf 100644 --- a/openvpn/openssl/crypto/tls1prf.hpp +++ b/openvpn/openssl/crypto/tls1prf.hpp @@ -20,11 +20,17 @@ // If not, see . #pragma once +#if (OPENSSL_VERSION_NUMBER >= 0x30000000L) +#include +#include +#endif #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) #include #endif + + #include namespace openvpn { @@ -33,7 +39,51 @@ namespace OpenSSLCrypto { class TLS1PRF { public: -#if OPENSSL_VERSION_NUMBER >= 0x10100000L +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + static bool PRF(unsigned char *label, + const size_t label_len, + const unsigned char *sec, + const size_t slen, + unsigned char *out1, + const size_t olen) + + { + using EVP_KDF_ptr = std::unique_ptr; + using EVP_KDF_CTX_ptr = std::unique_ptr; + + EVP_KDF_ptr kdf{::EVP_KDF_fetch(NULL, "TLS1-PRF", NULL), ::EVP_KDF_free}; + if (!kdf) + { + return false; + } + + EVP_KDF_CTX_ptr kctx{::EVP_KDF_CTX_new(kdf.get()), ::EVP_KDF_CTX_free}; + + if (!kctx) + { + return false; + } + + OSSL_PARAM params[4]; + params[0] = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, + const_cast(SN_md5_sha1), + strlen(SN_md5_sha1)); + params[1] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SECRET, + const_cast(sec), + slen); + params[2] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SEED, + label, + label_len); + params[3] = OSSL_PARAM_construct_end(); + + if (::EVP_KDF_derive(kctx.get(), out1, olen, params) <= 0) + { + return false; + } + + return true; + } +#elif OPENSSL_VERSION_NUMBER >= 0x10100000L static bool PRF(unsigned char *label, const size_t label_len, const unsigned char *sec,