[Openvpn-devel,M] Change in openvpn[master]: Implement generating TLS 1.0 PRF using new OpenSSL 3.0 APIs

Message ID 61eeb6676f4c720e1ae1b76b62e2089ce9d691c6-HTML@gerrit.openvpn.net
State Superseded
Headers show
Series [Openvpn-devel,M] Change in openvpn[master]: Implement generating TLS 1.0 PRF using new OpenSSL 3.0 APIs | expand

Commit Message

flichtenheld (Code Review) Nov. 21, 2023, 7:36 p.m. UTC
Attention is currently required from: flichtenheld.

Hello flichtenheld,

I'd like you to do a code review.
Please visit

    http://gerrit.openvpn.net/c/openvpn/+/457?usp=email

to review the following change.


Change subject: Implement generating TLS 1.0 PRF using new OpenSSL 3.0 APIs
......................................................................

Implement generating TLS 1.0 PRF using new OpenSSL 3.0 APIs

OpenSSL 3.0 introduced a new API for doing key derivation. So this leaves
use now with three different implementation for 1.0.2, 1.1.x and 3.x.

This was initially done to maybe still have a working TLS 1.0 PRF when
using OpenSSL 3.0, it gives the same error as with the older API but
since moving to a new API is always good, we use the new API when using
OpenSSL 3.0. We also print the internal OpenSSL error message when
the KDF fails.

Change-Id: Ic74195a4ed340547c5e862dc2438f95be318c286
Signed-off-by: Arne Schwabe <arne@rfc2549.org>
---
M src/openvpn/crypto_openssl.c
1 file changed, 50 insertions(+), 1 deletion(-)



  git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/57/457/1

Patch

diff --git a/src/openvpn/crypto_openssl.c b/src/openvpn/crypto_openssl.c
index fe1254f..7351a5f 100644
--- a/src/openvpn/crypto_openssl.c
+++ b/src/openvpn/crypto_openssl.c
@@ -54,6 +54,7 @@ 
 #endif
 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
 #include <openssl/provider.h>
+#include <openssl/core_names.h>
 #endif
 
 #if defined(_WIN32) && defined(OPENSSL_NO_EC)
@@ -1373,8 +1374,56 @@ 
 {
     return CRYPTO_memcmp(a, b, size);
 }
+#if (OPENSSL_VERSION_NUMBER >= 0x3000000L) && !defined(LIBRESSL_VERSION_NUMBER)
+bool
+ssl_tls1_PRF(const uint8_t *seed, int seed_len, const uint8_t *secret,
+             int secret_len, uint8_t *output, int output_len)
+{
+    bool ret = true;
+    EVP_KDF_CTX *kctx = NULL;
 
-#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER)
+
+    EVP_KDF *kdf = EVP_KDF_fetch(NULL, "TLS1-PRF", NULL);
+    if (!kdf)
+    {
+        goto err;
+    }
+
+    kctx = EVP_KDF_CTX_new(kdf);
+
+    if (!kctx)
+    {
+        goto err;
+    }
+
+    OSSL_PARAM params[4];
+
+    params[0] = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
+                                                 SN_md5_sha1, strlen(SN_md5_sha1));
+    params[1] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SECRET,
+                                                  secret, (size_t) secret_len);
+    params[2] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SEED,
+                                                  seed, (size_t) seed_len);
+    params[3] = OSSL_PARAM_construct_end();
+
+    if (EVP_KDF_derive(kctx, output, output_len, params) <= 0)
+    {
+        crypto_msg(D_TLS_DEBUG_LOW, "Generating TLS 1.0 PRF using "
+                   "EVP_KDF_derive failed");
+        goto err;
+    }
+
+    goto out;
+
+err:
+    ret = false;
+out:
+    EVP_KDF_free(kdf);
+    EVP_KDF_free(kdf);
+
+    return ret;
+}
+#elif (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER)
 bool
 ssl_tls1_PRF(const uint8_t *seed, int seed_len, const uint8_t *secret,
              int secret_len, uint8_t *output, int output_len)