Blob Blame History Raw
From 3b512b3127b2ad733460d30bf8def2b5553bc648 Mon Sep 17 00:00:00 2001
From: rpm-build <rpm-build>
Date: Thu, 29 Aug 2019 14:28:57 +0200
Subject: [PATCH] Remove or backport OpenSSL features

Signed-off-by: rpm-build <rpm-build>
---
 src/node_constants.cc                         |  12 +-
 src/node_crypto.cc                            | 268 ++++++++++++++++--
 src/node_crypto.h                             |  22 ++
 test/parallel/test-crypto-authenticated.js    |   4 +-
 test/parallel/test-crypto-keygen.js           |   8 +-
 test/parallel/test-crypto-pbkdf2.js           |  18 --
 .../test-tls-client-getephemeralkeyinfo.js    |   1 -
 test/parallel/test-tls-passphrase.js          |   2 +-
 8 files changed, 291 insertions(+), 44 deletions(-)

diff --git a/src/node_constants.cc b/src/node_constants.cc
index 9cd50fe..65f3159 100644
--- a/src/node_constants.cc
+++ b/src/node_constants.cc
@@ -951,8 +951,12 @@ void DefineOpenSSLConstants(Local<Object> target) {
     NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_RAND);
 # endif
 
-# ifdef ENGINE_METHOD_EC
-    NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_EC);
+# ifdef ENGINE_METHOD_ECDH
+    NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_ECDH);
+# endif
+
+# ifdef ENGINE_METHOD_ECDSA
+    NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_ECDSA);
 # endif
 
 # ifdef ENGINE_METHOD_CIPHERS
@@ -963,6 +967,10 @@ void DefineOpenSSLConstants(Local<Object> target) {
     NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_DIGESTS);
 # endif
 
+# ifdef ENGINE_METHOD_STORE
+    NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_STORE);
+# endif
+
 # ifdef ENGINE_METHOD_PKEY_METHS
     NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_PKEY_METHS);
 # endif
diff --git a/src/node_crypto.cc b/src/node_crypto.cc
index 1d9214f..17c6d77 100644
--- a/src/node_crypto.cc
+++ b/src/node_crypto.cc
@@ -109,6 +109,137 @@ struct OpenSSLBufferDeleter {
 };
 using OpenSSLBuffer = std::unique_ptr<char[], OpenSSLBufferDeleter>;
 
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+static void RSA_get0_key(const RSA* r, const BIGNUM** n, const BIGNUM** e,
+                         const BIGNUM** d) {
+  if (n != nullptr) {
+    *n = r->n;
+  }
+  if (e != nullptr) {
+    *e = r->e;
+  }
+  if (d != nullptr) {
+    *d = r->d;
+  }
+}
+
+static void DH_get0_pqg(const DH* dh, const BIGNUM** p, const BIGNUM** q,
+                        const BIGNUM** g) {
+  if (p != nullptr) {
+    *p = dh->p;
+  }
+  if (q != nullptr) {
+    *q = dh->q;
+  }
+  if (g != nullptr) {
+    *g = dh->g;
+  }
+}
+
+static int DH_set0_pqg(DH* dh, BIGNUM* p, BIGNUM* q, BIGNUM* g) {
+  if ((dh->p == nullptr && p == nullptr) ||
+      (dh->g == nullptr && g == nullptr)) {
+    return 0;
+  }
+
+  if (p != nullptr) {
+    BN_free(dh->p);
+    dh->p = p;
+  }
+  if (q != nullptr) {
+    BN_free(dh->q);
+    dh->q = q;
+  }
+  if (g != nullptr) {
+    BN_free(dh->g);
+    dh->g = g;
+  }
+
+  return 1;
+}
+
+static void DH_get0_key(const DH* dh, const BIGNUM** pub_key,
+                        const BIGNUM** priv_key) {
+  if (pub_key != nullptr) {
+    *pub_key = dh->pub_key;
+  }
+  if (priv_key != nullptr) {
+    *priv_key = dh->priv_key;
+  }
+}
+
+static int DH_set0_key(DH* dh, BIGNUM* pub_key, BIGNUM* priv_key) {
+  if (pub_key != nullptr) {
+    BN_free(dh->pub_key);
+    dh->pub_key = pub_key;
+  }
+  if (priv_key != nullptr) {
+    BN_free(dh->priv_key);
+    dh->priv_key = priv_key;
+  }
+
+  return 1;
+}
+
+static const SSL_METHOD* TLS_method() { return SSLv23_method(); }
+
+static void SSL_SESSION_get0_ticket(const SSL_SESSION* s,
+                                    const unsigned char** tick, size_t* len) {
+  *len = s->tlsext_ticklen;
+  if (tick != nullptr) {
+    *tick = s->tlsext_tick;
+  }
+}
+
+#define SSL_get_tlsext_status_type(ssl) (ssl->tlsext_status_type)
+
+static int X509_STORE_up_ref(X509_STORE* store) {
+  CRYPTO_add(&store->references, 1, CRYPTO_LOCK_X509_STORE);
+  return 1;
+}
+
+static int X509_up_ref(X509* cert) {
+  CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509);
+  return 1;
+}
+
+HMAC_CTX* HMAC_CTX_new() {
+  HMAC_CTX* ctx = Malloc<HMAC_CTX>(1);
+  HMAC_CTX_init(ctx);
+  return ctx;
+}
+
+// Disable all TLS version lower than the version argument
+int SSL_CTX_set_min_proto_version(SSL_CTX *ctx, int version) {
+    switch (version) {
+        [[gnu::fallthrough]] case TLS1_2_VERSION:
+            SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_1);
+        [[gnu::fallthrough]] case TLS1_1_VERSION:
+            SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1);
+        [[gnu::fallthrough]] case TLS1_VERSION:
+            SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3);
+            return 1;
+        default:
+            return 0;  // unsupported
+    }
+}
+// Disable all TLS version higher than the version argument
+int SSL_CTX_set_max_proto_version(SSL_CTX *ctx, int version) {
+    switch (version) {
+        [[gnu::fallthrough]] case TLS1_VERSION:
+            SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_1);
+        [[gnu::fallthrough]] case TLS1_1_VERSION:
+            SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_2);
+        [[gnu::fallthrough]] case TLS1_2_VERSION:
+            return 1;
+        default:
+            return 0;  // unsupported
+    }
+}
+
+#endif  // OPENSSL_VERSION_NUMBER < 0x10100000L
+
+
 static const char* const root_certs[] = {
 #include "node_root_certs.h"  // NOLINT(build/include_order)
 };
@@ -125,11 +256,19 @@ template void SSLWrap<TLSWrap>::AddMethods(Environment* env,
 template void SSLWrap<TLSWrap>::ConfigureSecureContext(SecureContext* sc);
 template void SSLWrap<TLSWrap>::SetSNIContext(SecureContext* sc);
 template int SSLWrap<TLSWrap>::SetCACerts(SecureContext* sc);
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+template SSL_SESSION* SSLWrap<TLSWrap>::GetSessionCallback(
+    SSL* s,
+    unsigned char* key,
+    int len,
+    int* copy);
+#else
 template SSL_SESSION* SSLWrap<TLSWrap>::GetSessionCallback(
     SSL* s,
     const unsigned char* key,
     int len,
     int* copy);
+#endif
 template int SSLWrap<TLSWrap>::NewSessionCallback(SSL* s,
                                                   SSL_SESSION* sess);
 template void SSLWrap<TLSWrap>::OnClientHello(
@@ -148,6 +287,34 @@ template int SSLWrap<TLSWrap>::SelectALPNCallback(
     void* arg);
 
 
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+static Mutex* mutexes;
+
+static void crypto_threadid_cb(CRYPTO_THREADID* tid) {
+  static_assert(sizeof(uv_thread_t) <= sizeof(void*),
+                "uv_thread_t does not fit in a pointer");
+  CRYPTO_THREADID_set_pointer(tid, reinterpret_cast<void*>(uv_thread_self()));
+}
+
+
+static void crypto_lock_init(void) {
+  mutexes = new Mutex[CRYPTO_num_locks()];
+}
+
+
+static void crypto_lock_cb(int mode, int n, const char* file, int line) {
+  CHECK(!(mode & CRYPTO_LOCK) ^ !(mode & CRYPTO_UNLOCK));
+  CHECK(!(mode & CRYPTO_READ) ^ !(mode & CRYPTO_WRITE));
+
+  auto mutex = &mutexes[n];
+  if (mode & CRYPTO_LOCK)
+    mutex->Lock();
+  else
+    mutex->Unlock();
+}
+#endif
+
+
 static int PasswordCallback(char* buf, int size, int rwflag, void* u) {
   if (u) {
     size_t buflen = static_cast<size_t>(size);
@@ -401,7 +568,7 @@ void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
 
   int min_version = args[1].As<Int32>()->Value();
   int max_version = args[2].As<Int32>()->Value();
-  const SSL_METHOD* method = TLS_method();
+  const SSL_METHOD* method = SSLv23_method();
 
   if (args[0]->IsString()) {
     const node::Utf8Value sslmethod(env->isolate(), args[0]);
@@ -425,9 +592,9 @@ void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
     } else if (strcmp(*sslmethod, "SSLv23_method") == 0) {
       // noop
     } else if (strcmp(*sslmethod, "SSLv23_server_method") == 0) {
-      method = TLS_server_method();
+      method = SSLv23_server_method();
     } else if (strcmp(*sslmethod, "SSLv23_client_method") == 0) {
-      method = TLS_client_method();
+      method = SSLv23_client_method();
     } else if (strcmp(*sslmethod, "TLS_method") == 0) {
       min_version = 0;
       max_version = 0;
@@ -437,33 +604,33 @@ void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
     } else if (strcmp(*sslmethod, "TLSv1_server_method") == 0) {
       min_version = TLS1_VERSION;
       max_version = TLS1_VERSION;
-      method = TLS_server_method();
+      method = SSLv23_server_method();
     } else if (strcmp(*sslmethod, "TLSv1_client_method") == 0) {
       min_version = TLS1_VERSION;
       max_version = TLS1_VERSION;
-      method = TLS_client_method();
+      method = SSLv23_client_method();
     } else if (strcmp(*sslmethod, "TLSv1_1_method") == 0) {
       min_version = TLS1_1_VERSION;
       max_version = TLS1_1_VERSION;
     } else if (strcmp(*sslmethod, "TLSv1_1_server_method") == 0) {
       min_version = TLS1_1_VERSION;
       max_version = TLS1_1_VERSION;
-      method = TLS_server_method();
+      method = SSLv23_server_method();
     } else if (strcmp(*sslmethod, "TLSv1_1_client_method") == 0) {
       min_version = TLS1_1_VERSION;
       max_version = TLS1_1_VERSION;
-      method = TLS_client_method();
+      method = SSLv23_client_method();
     } else if (strcmp(*sslmethod, "TLSv1_2_method") == 0) {
       min_version = TLS1_2_VERSION;
       max_version = TLS1_2_VERSION;
     } else if (strcmp(*sslmethod, "TLSv1_2_server_method") == 0) {
       min_version = TLS1_2_VERSION;
       max_version = TLS1_2_VERSION;
-      method = TLS_server_method();
+      method = SSLv23_server_method();
     } else if (strcmp(*sslmethod, "TLSv1_2_client_method") == 0) {
       min_version = TLS1_2_VERSION;
       max_version = TLS1_2_VERSION;
-      method = TLS_client_method();
+      method = SSLv23_client_method();
     } else {
       return env->ThrowError("Unknown method");
     }
@@ -498,6 +665,7 @@ void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
     max_version = TLS1_2_VERSION;
   }
   SSL_CTX_set_max_proto_version(sc->ctx_.get(), max_version);
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
   // OpenSSL 1.1.0 changed the ticket key size, but the OpenSSL 1.0.x size was
   // exposed in the public API. To retain compatibility, install a callback
   // which restores the old algorithm.
@@ -507,6 +675,7 @@ void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
     return env->ThrowError("Error generating ticket keys");
   }
   SSL_CTX_set_tlsext_ticket_key_cb(sc->ctx_.get(), TicketCompatibilityCallback);
+#endif
 }
 
 
@@ -937,6 +1106,11 @@ void SecureContext::SetECDHCurve(const FunctionCallbackInfo<Value>& args) {
 
   node::Utf8Value curve(env->isolate(), args[0]);
 
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+  SSL_CTX_set_options(sc->ctx_.get(), SSL_OP_SINGLE_ECDH_USE);
+  SSL_CTX_set_ecdh_auto(sc->ctx_.get(), 1);
+#endif
+
   if (strcmp(*curve, "auto") == 0)
     return;
 
@@ -1191,9 +1365,17 @@ void SecureContext::GetTicketKeys(const FunctionCallbackInfo<Value>& args) {
   ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
 
   Local<Object> buff = Buffer::New(wrap->env(), 48).ToLocalChecked();
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
   memcpy(Buffer::Data(buff), wrap->ticket_key_name_, 16);
   memcpy(Buffer::Data(buff) + 16, wrap->ticket_key_hmac_, 16);
   memcpy(Buffer::Data(buff) + 32, wrap->ticket_key_aes_, 16);
+#else
+  if (SSL_CTX_get_tlsext_ticket_keys(wrap->ctx_.get(),
+                                     Buffer::Data(buff),
+                                     Buffer::Length(buff)) != 1) {
+    return wrap->env()->ThrowError("Failed to fetch tls ticket keys");
+  }
+#endif
 
   args.GetReturnValue().Set(buff);
 #endif  // !def(OPENSSL_NO_TLSEXT) && def(SSL_CTX_get_tlsext_ticket_keys)
@@ -1217,9 +1399,17 @@ void SecureContext::SetTicketKeys(const FunctionCallbackInfo<Value>& args) {
         env, "Ticket keys length must be 48 bytes");
   }
 
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
   memcpy(wrap->ticket_key_name_, Buffer::Data(args[0]), 16);
   memcpy(wrap->ticket_key_hmac_, Buffer::Data(args[0]) + 16, 16);
   memcpy(wrap->ticket_key_aes_, Buffer::Data(args[0]) + 32, 16);
+#else
+  if (SSL_CTX_set_tlsext_ticket_keys(wrap->ctx_.get(),
+                                     Buffer::Data(args[0]),
+                                     Buffer::Length(args[0])) != 1) {
+    return env->ThrowError("Failed to fetch tls ticket keys");
+  }
+#endif
 
   args.GetReturnValue().Set(true);
 #endif  // !def(OPENSSL_NO_TLSEXT) && def(SSL_CTX_get_tlsext_ticket_keys)
@@ -1227,6 +1417,14 @@ void SecureContext::SetTicketKeys(const FunctionCallbackInfo<Value>& args) {
 
 
 void SecureContext::SetFreeListLength(const FunctionCallbackInfo<Value>& args) {
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+  // |freelist_max_len| was removed in OpenSSL 1.1.0. In that version OpenSSL
+  // mallocs and frees buffers directly, without the use of a freelist.
+  SecureContext* wrap;
+  ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
+
+  wrap->ctx_->freelist_max_len = args[0]->Int32Value();
+#endif
 }
 
 
@@ -1323,6 +1521,7 @@ int SecureContext::TicketKeyCallback(SSL* ssl,
 }
 
 
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
 int SecureContext::TicketCompatibilityCallback(SSL* ssl,
                                                unsigned char* name,
                                                unsigned char* iv,
@@ -1357,6 +1556,7 @@ int SecureContext::TicketCompatibilityCallback(SSL* ssl,
   }
   return 1;
 }
+#endif
 
 
 void SecureContext::CtxGetter(const FunctionCallbackInfo<Value>& info) {
@@ -1433,11 +1633,19 @@ void SSLWrap<Base>::ConfigureSecureContext(SecureContext* sc) {
 }
 
 
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+template <class Base>
+SSL_SESSION* SSLWrap<Base>::GetSessionCallback(SSL* s,
+                                               unsigned char* key,
+                                               int len,
+                                               int* copy) {
+#else
 template <class Base>
 SSL_SESSION* SSLWrap<Base>::GetSessionCallback(SSL* s,
                                                const unsigned char* key,
                                                int len,
                                                int* copy) {
+#endif
   Base* w = static_cast<Base*>(SSL_get_app_data(s));
 
   *copy = 0;
@@ -2094,6 +2302,7 @@ void SSLWrap<Base>::GetEphemeralKeyInfo(
                   Integer::New(env->isolate(), EVP_PKEY_bits(key))).FromJust();
         break;
       case EVP_PKEY_EC:
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
       // TODO(shigeki) Change this to EVP_PKEY_X25519 and add EVP_PKEY_X448
       // after upgrading to 1.1.1.
       case NID_X25519:
@@ -2114,9 +2323,24 @@ void SSLWrap<Base>::GetEphemeralKeyInfo(
                                   curve_name)).FromJust();
           info->Set(context, env->size_string(),
                     Integer::New(env->isolate(),
-                                 EVP_PKEY_bits(key))).FromJust();
+                                  EVP_PKEY_bits(key))).FromJust();
         }
         break;
+#else
+        {
+          EC_KEY* ec = EVP_PKEY_get1_EC_KEY(key);
+          int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec));
+          EC_KEY_free(ec);
+          info->Set(context, env->type_string(),
+                    FIXED_ONE_BYTE_STRING(env->isolate(), "ECDH")).FromJust();
+          info->Set(context, env->name_string(),
+                    OneByteString(args.GetIsolate(),
+                                  OBJ_nid2sn(nid))).FromJust();
+          info->Set(context, env->size_string(),
+                    Integer::New(env->isolate(),
+                                  EVP_PKEY_bits(key))).FromJust();
+         }
+#endif
     }
     EVP_PKEY_free(key);
   }
@@ -2776,10 +3000,10 @@ bool CipherBase::InitAuthenticated(const char* cipher_type, int iv_len,
   CHECK(IsAuthenticatedMode());
   MarkPopErrorOnReturn mark_pop_error_on_return;
 
-  if (!EVP_CIPHER_CTX_ctrl(ctx_.get(),
-                           EVP_CTRL_AEAD_SET_IVLEN,
-                           iv_len,
-                           nullptr)) {
+  // TODO(tniessen) Use EVP_CTRL_AEAD_SET_IVLEN when migrating to OpenSSL 1.1.0
+  static_assert(EVP_CTRL_CCM_SET_IVLEN == EVP_CTRL_GCM_SET_IVLEN,
+                "OpenSSL constants differ between GCM and CCM");
+  if (!EVP_CIPHER_CTX_ctrl(ctx_.get(), EVP_CTRL_GCM_SET_IVLEN, iv_len, nullptr)) {
     env()->ThrowError("Invalid IV length");
     return false;
   }
@@ -2910,6 +3134,7 @@ void CipherBase::SetAuthTag(const FunctionCallbackInfo<Value>& args) {
           "Valid GCM tag lengths are 4, 8, 12, 13, 14, 15, 16.", tag_len);
       ProcessEmitDeprecationWarning(cipher->env(), msg, "DEP0090");
     }
+#ifndef OPENSSL_NO_OCB
   } else if (mode == EVP_CIPH_OCB_MODE) {
     // At this point, the tag length is already known and must match the
     // length of the given authentication tag.
@@ -2921,6 +3146,7 @@ void CipherBase::SetAuthTag(const FunctionCallbackInfo<Value>& args) {
           "Invalid authentication tag length: %u", tag_len);
       return cipher->env()->ThrowError(msg);
     }
+#endif // OPENSSL_NO_OCB
   }
 
   // Note: we don't use std::min() here to work around a header conflict.
@@ -3140,8 +3366,10 @@ bool CipherBase::Final(unsigned char** out, int* out_len) {
         CHECK(mode == EVP_CIPH_GCM_MODE);
         auth_tag_len_ = sizeof(auth_tag_);
       }
-      CHECK_EQ(1, EVP_CIPHER_CTX_ctrl(ctx_.get(), EVP_CTRL_AEAD_GET_TAG,
-                      auth_tag_len_,
+      // TOOD(tniessen) Use EVP_CTRL_AEAP_GET_TAG in OpenSSL 1.1.0
+      static_assert(EVP_CTRL_CCM_GET_TAG == EVP_CTRL_GCM_GET_TAG,
+                    "OpenSSL constants differ between GCM and CCM");
+      CHECK_EQ(1, EVP_CIPHER_CTX_ctrl(ctx_.get(), EVP_CTRL_GCM_GET_TAG, auth_tag_len_,
                       reinterpret_cast<unsigned char*>(auth_tag_)));
     }
   }
@@ -3417,12 +3645,14 @@ void Hash::HashDigest(const FunctionCallbackInfo<Value>& args) {
 
 SignBase::Error SignBase::Init(const char* sign_type) {
   CHECK_NULL(mdctx_);
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
   // Historically, "dss1" and "DSS1" were DSA aliases for SHA-1
   // exposed through the public API.
   if (strcmp(sign_type, "dss1") == 0 ||
       strcmp(sign_type, "DSS1") == 0) {
     sign_type = "SHA1";
   }
+#endif
   const EVP_MD* md = EVP_get_digestbyname(sign_type);
   if (md == nullptr)
     return kSignUnknownDigest;
@@ -5587,6 +5817,12 @@ void InitCryptoOnce() {
   SSL_library_init();
   OpenSSL_add_all_algorithms();
 
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+  crypto_lock_init();
+  CRYPTO_set_locking_callback(crypto_lock_cb);
+  CRYPTO_THREADID_set_callback(crypto_threadid_cb);
+#endif
+
 #ifdef NODE_FIPS_MODE
   /* Override FIPS settings in cnf file, if needed. */
   unsigned long err = 0;  // NOLINT(runtime/int)
diff --git a/src/node_crypto.h b/src/node_crypto.h
index b64a8c2..2e6042f 100644
--- a/src/node_crypto.h
+++ b/src/node_crypto.h
@@ -44,8 +44,10 @@
 #endif  // !OPENSSL_NO_ENGINE
 #include <openssl/err.h>
 #include <openssl/evp.h>
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
 // TODO(shigeki) Remove this after upgrading to 1.1.1
 #include <openssl/obj_mac.h>
+#endif
 #include <openssl/pem.h>
 #include <openssl/x509.h>
 #include <openssl/x509v3.h>
@@ -53,6 +55,26 @@
 #include <openssl/rand.h>
 #include <openssl/pkcs12.h>
 
+// OpenSSL backport shims
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+
+#define EVP_CTRL_AEAD_SET_TAG EVP_CTRL_CCM_SET_TAG
+#define EVP_MD_CTX_free EVP_MD_CTX_destroy
+#define EVP_MD_CTX_new EVP_MD_CTX_create
+
+#define OPENSSL_EC_EXPLICIT_CURVE 0x0
+
+inline void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX* ctx) { EVP_CIPHER_CTX_cleanup(ctx); }
+inline void HMAC_CTX_free(HMAC_CTX* ctx) { if (ctx == nullptr) { return; } HMAC_CTX_cleanup(ctx); free(ctx); }
+inline void OPENSSL_clear_free(void* ptr, size_t len) { OPENSSL_cleanse(ptr, len); OPENSSL_free(ptr); }
+
+inline int BN_bn2binpad(const BIGNUM* a, unsigned char *to, int tolen) {
+    if (tolen < 0) { return -1; }
+    OPENSSL_cleanse(to, tolen);
+    return BN_bn2bin(a, to);
+}
+#endif // OPENSSL_VERSION_NUMBER < 0x10100000L
+
 namespace node {
 namespace crypto {
 
diff --git a/test/parallel/test-crypto-authenticated.js b/test/parallel/test-crypto-authenticated.js
index dc19a7b..5e94d41 100644
--- a/test/parallel/test-crypto-authenticated.js
+++ b/test/parallel/test-crypto-authenticated.js
@@ -425,7 +425,7 @@ for (const test of TEST_CASES) {
 // Test that create(De|C)ipher(iv)? throws if the mode is CCM or OCB and no
 // authentication tag has been specified.
 {
-  for (const mode of ['ccm', 'ocb']) {
+  for (const mode of ['ccm']) {
     assert.throws(() => {
       crypto.createCipheriv(`aes-256-${mode}`,
                             'FxLKsqdmv0E9xrQhp0b1ZgI0K7JFZJM8',
@@ -585,7 +585,7 @@ for (const test of TEST_CASES) {
   const key = Buffer.from('0123456789abcdef', 'utf8');
   const iv = Buffer.from('0123456789ab', 'utf8');
 
-  for (const mode of ['gcm', 'ocb']) {
+  for (const mode of ['gcm']) {
     for (const authTagLength of mode === 'gcm' ? [undefined, 8] : [8]) {
       const cipher = crypto.createCipheriv(`aes-128-${mode}`, key, iv, {
         authTagLength
diff --git a/test/parallel/test-crypto-keygen.js b/test/parallel/test-crypto-keygen.js
index 0ffaa1c..7c567f3 100644
--- a/test/parallel/test-crypto-keygen.js
+++ b/test/parallel/test-crypto-keygen.js
@@ -171,7 +171,7 @@ function convertDERToPEM(label, der) {
     // Since the private key is encrypted, signing shouldn't work anymore.
     assert.throws(() => {
       testSignVerify(publicKey, privateKey);
-    }, /bad decrypt|asn1 encoding routines/);
+    }, /bad decrypt|bad password read|asn1 encoding routines/);
 
     const key = { key: privateKey, passphrase: 'secret' };
     testEncryptDecrypt(publicKey, key);
@@ -209,7 +209,7 @@ function convertDERToPEM(label, der) {
     // Since the private key is encrypted, signing shouldn't work anymore.
     assert.throws(() => {
       testSignVerify(publicKey, privateKey);
-    }, /bad decrypt|asn1 encoding routines/);
+    }, /bad decrypt|bad password read|asn1 encoding routines/);
 
     // Signing should work with the correct password.
     testSignVerify(publicKey, {
@@ -269,7 +269,7 @@ function convertDERToPEM(label, der) {
     // Since the private key is encrypted, signing shouldn't work anymore.
     assert.throws(() => {
       testSignVerify(publicKey, privateKey);
-    }, /bad decrypt|asn1 encoding routines/);
+    }, /bad decrypt|bad password read|asn1 encoding routines/);
 
     testSignVerify(publicKey, { key: privateKey, passphrase: 'secret' });
   }));
@@ -302,7 +302,7 @@ function convertDERToPEM(label, der) {
     // Since the private key is encrypted, signing shouldn't work anymore.
     assert.throws(() => {
       testSignVerify(publicKey, privateKey);
-    }, /bad decrypt|asn1 encoding routines/);
+    }, /bad decrypt|bad password read|asn1 encoding routines/);
 
     testSignVerify(publicKey, {
       key: privateKey,
diff --git a/test/parallel/test-crypto-pbkdf2.js b/test/parallel/test-crypto-pbkdf2.js
index 0f5d461..8701d10 100644
--- a/test/parallel/test-crypto-pbkdf2.js
+++ b/test/parallel/test-crypto-pbkdf2.js
@@ -216,21 +216,3 @@ crypto.pbkdf2Sync(new Float32Array(10), 'salt', 8, 8, 'sha256');
 crypto.pbkdf2Sync('pass', new Float32Array(10), 8, 8, 'sha256');
 crypto.pbkdf2Sync(new Float64Array(10), 'salt', 8, 8, 'sha256');
 crypto.pbkdf2Sync('pass', new Float64Array(10), 8, 8, 'sha256');
-
-assert.throws(
-  () => crypto.pbkdf2('pass', 'salt', 8, 8, 'md55', common.mustNotCall()),
-  {
-    code: 'ERR_CRYPTO_INVALID_DIGEST',
-    name: 'TypeError [ERR_CRYPTO_INVALID_DIGEST]',
-    message: 'Invalid digest: md55'
-  }
-);
-
-assert.throws(
-  () => crypto.pbkdf2Sync('pass', 'salt', 8, 8, 'md55'),
-  {
-    code: 'ERR_CRYPTO_INVALID_DIGEST',
-    name: 'TypeError [ERR_CRYPTO_INVALID_DIGEST]',
-    message: 'Invalid digest: md55'
-  }
-);
diff --git a/test/parallel/test-tls-client-getephemeralkeyinfo.js b/test/parallel/test-tls-client-getephemeralkeyinfo.js
index a5db18a..277d36c 100644
--- a/test/parallel/test-tls-client-getephemeralkeyinfo.js
+++ b/test/parallel/test-tls-client-getephemeralkeyinfo.js
@@ -55,4 +55,3 @@ test(1024, 'DH', undefined, 'DHE-RSA-AES128-GCM-SHA256');
 test(2048, 'DH', undefined, 'DHE-RSA-AES128-GCM-SHA256');
 test(256, 'ECDH', 'prime256v1', 'ECDHE-RSA-AES128-GCM-SHA256');
 test(521, 'ECDH', 'secp521r1', 'ECDHE-RSA-AES128-GCM-SHA256');
-test(253, 'ECDH', 'X25519', 'ECDHE-RSA-AES128-GCM-SHA256');
diff --git a/test/parallel/test-tls-passphrase.js b/test/parallel/test-tls-passphrase.js
index 6ed19c7..b183309 100644
--- a/test/parallel/test-tls-passphrase.js
+++ b/test/parallel/test-tls-passphrase.js
@@ -221,7 +221,7 @@ server.listen(0, common.mustCall(function() {
   }, common.mustCall());
 })).unref();
 
-const errMessagePassword = /bad decrypt/;
+const errMessagePassword = /bad password read/;
 
 // Missing passphrase
 assert.throws(function() {
-- 
2.21.0