Blob Blame History Raw
From 356ece933457ff7216658236ec5cf05f906e8f69 Mon Sep 17 00:00:00 2001
From: Your Name <you@example.com>
Date: Fri, 14 Sep 2018 13:39:05 +0000
Subject: [PATCH 2/2] Remove OpenSSL 1.0.2 features

---
 src/node_crypto.cc                         | 150 ++++++++++++++++++++---------
 src/node_crypto.h                          |  28 ++++--
 test/parallel/test-crypto-authenticated.js |   6 +-
 3 files changed, 128 insertions(+), 56 deletions(-)

diff --git a/src/node_crypto.cc b/src/node_crypto.cc
index 7bdb1b1..6111e2e 100644
--- a/src/node_crypto.cc
+++ b/src/node_crypto.cc
@@ -1077,8 +1077,8 @@ 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_, SSL_OP_SINGLE_ECDH_USE);
-  SSL_CTX_set_ecdh_auto(sc->ctx_, 1);
+  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)
@@ -1340,7 +1340,7 @@ void SecureContext::GetTicketKeys(const FunctionCallbackInfo<Value>& args) {
   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_,
+  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");
@@ -1374,7 +1374,7 @@ void SecureContext::SetTicketKeys(const FunctionCallbackInfo<Value>& args) {
   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_,
+  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");
@@ -2804,14 +2804,14 @@ void CipherBase::Init(const char* cipher_type,
                                iv);
   CHECK_NE(key_len, 0);
 
-  ctx_.reset(EVP_CIPHER_CTX_new());
+  ctx_ = EVP_CIPHER_CTX_new();
 
   const int mode = EVP_CIPHER_mode(cipher);
   if (mode == EVP_CIPH_WRAP_MODE)
-    EVP_CIPHER_CTX_set_flags(ctx_.get(), EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
+    EVP_CIPHER_CTX_set_flags(ctx_, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
 
   const bool encrypt = (kind_ == kCipher);
-  if (1 != EVP_CipherInit_ex(ctx_.get(), cipher, nullptr,
+  if (1 != EVP_CipherInit_ex(ctx_, cipher, nullptr,
                              nullptr, nullptr, encrypt)) {
     return ThrowCryptoError(env(), ERR_get_error(),
                             "Failed to initialize cipher");
@@ -2832,9 +2832,9 @@ void CipherBase::Init(const char* cipher_type,
       return;
   }
 
-  CHECK_EQ(1, EVP_CIPHER_CTX_set_key_length(ctx_.get(), key_len));
+  CHECK_EQ(1, EVP_CIPHER_CTX_set_key_length(ctx_, key_len));
 
-  if (1 != EVP_CipherInit_ex(ctx_.get(),
+  if (1 != EVP_CipherInit_ex(ctx_,
                              nullptr,
                              nullptr,
                              reinterpret_cast<unsigned char*>(key),
@@ -2871,8 +2871,8 @@ void CipherBase::Init(const FunctionCallbackInfo<Value>& args) {
 
 static bool IsSupportedAuthenticatedMode(int mode) {
   return mode == EVP_CIPH_CCM_MODE ||
-         mode == EVP_CIPH_GCM_MODE ||
-         mode == EVP_CIPH_OCB_MODE;
+         mode == EVP_CIPH_GCM_MODE;
+         // mode == EVP_CIPH_OCB_MODE;
 }
 
 void CipherBase::InitIv(const char* cipher_type,
@@ -2906,13 +2906,13 @@ void CipherBase::InitIv(const char* cipher_type,
     return env()->ThrowError("Invalid IV length");
   }
 
-  ctx_.reset(EVP_CIPHER_CTX_new());
+  ctx_ = EVP_CIPHER_CTX_new();
 
   if (mode == EVP_CIPH_WRAP_MODE)
-    EVP_CIPHER_CTX_set_flags(ctx_.get(), EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
+    EVP_CIPHER_CTX_set_flags(ctx_, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
 
   const bool encrypt = (kind_ == kCipher);
-  if (1 != EVP_CipherInit_ex(ctx_.get(), cipher, nullptr,
+  if (1 != EVP_CipherInit_ex(ctx_, cipher, nullptr,
                              nullptr, nullptr, encrypt)) {
     return ThrowCryptoError(env(), ERR_get_error(),
                             "Failed to initialize cipher");
@@ -2924,12 +2924,13 @@ void CipherBase::InitIv(const char* cipher_type,
       return;
   }
 
-  if (!EVP_CIPHER_CTX_set_key_length(ctx_.get(), key_len)) {
-    ctx_.reset();
+  if (!EVP_CIPHER_CTX_set_key_length(ctx_, key_len)) {
+    EVP_CIPHER_CTX_free(ctx_);
+    ctx_ = nullptr;
     return env()->ThrowError("Invalid key length");
   }
 
-  if (1 != EVP_CipherInit_ex(ctx_.get(),
+  if (1 != EVP_CipherInit_ex(ctx_,
                              nullptr,
                              nullptr,
                              reinterpret_cast<const unsigned char*>(key),
@@ -2992,8 +2993,8 @@ bool CipherBase::InitAuthenticated(const char* cipher_type, int iv_len,
     return false;
   }
 
-  const int mode = EVP_CIPHER_CTX_mode(ctx_.get());
-  if (mode == EVP_CIPH_CCM_MODE || mode == EVP_CIPH_OCB_MODE) {
+  const int mode = EVP_CIPHER_CTX_mode(ctx_);
+  if (mode == EVP_CIPH_CCM_MODE) {
     if (auth_tag_len == kNoAuthTagLength) {
       char msg[128];
       snprintf(msg, sizeof(msg), "authTagLength required for %s", cipher_type);
@@ -3010,7 +3011,8 @@ bool CipherBase::InitAuthenticated(const char* cipher_type, int iv_len,
 #endif
 
     // Tell OpenSSL about the desired length.
-    if (!EVP_CIPHER_CTX_ctrl(ctx_.get(), EVP_CTRL_AEAD_SET_TAG, auth_tag_len,
+     if (!EVP_CIPHER_CTX_ctrl(ctx_, EVP_CTRL_CCM_SET_TAG, auth_tag_len,
+    // if (!EVP_CIPHER_CTX_ctrl(ctx_, EVP_CTRL_AEAD_SET_TAG, auth_tag_len,
                              nullptr)) {
       env()->ThrowError("Invalid authentication tag length");
       return false;
@@ -3049,7 +3051,7 @@ bool CipherBase::InitAuthenticated(const char* cipher_type, int iv_len,
 
 bool CipherBase::CheckCCMMessageLength(int message_len) {
   CHECK(ctx_);
-  CHECK(EVP_CIPHER_CTX_mode(ctx_.get()) == EVP_CIPH_CCM_MODE);
+  CHECK(EVP_CIPHER_CTX_mode(ctx_) == EVP_CIPH_CCM_MODE);
 
   if (message_len > max_message_size_) {
     env()->ThrowError("Message exceeds maximum size");
@@ -3063,7 +3065,7 @@ bool CipherBase::CheckCCMMessageLength(int message_len) {
 bool CipherBase::IsAuthenticatedMode() const {
   // Check if this cipher operates in an AEAD mode that we support.
   CHECK(ctx_);
-  const int mode = EVP_CIPHER_CTX_mode(ctx_.get());
+  const int mode = EVP_CIPHER_CTX_mode(ctx_);
   return IsSupportedAuthenticatedMode(mode);
 }
 
@@ -3098,7 +3100,7 @@ void CipherBase::SetAuthTag(const FunctionCallbackInfo<Value>& args) {
   }
 
   unsigned int tag_len = Buffer::Length(args[0]);
-  const int mode = EVP_CIPHER_CTX_mode(cipher->ctx_.get());
+  const int mode = EVP_CIPHER_CTX_mode(cipher->ctx_);
   if (mode == EVP_CIPH_GCM_MODE) {
     if (cipher->auth_tag_len_ != kNoAuthTagLength &&
         cipher->auth_tag_len_ != tag_len) {
@@ -3114,6 +3116,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");
     }
+/*
   } 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.
@@ -3125,6 +3128,7 @@ void CipherBase::SetAuthTag(const FunctionCallbackInfo<Value>& args) {
           "Invalid authentication tag length: %u", tag_len);
       return cipher->env()->ThrowError(msg);
     }
+*/
   }
 
   // Note: we don't use std::min() here to work around a header conflict.
@@ -3141,8 +3145,8 @@ void CipherBase::SetAuthTag(const FunctionCallbackInfo<Value>& args) {
 
 bool CipherBase::MaybePassAuthTagToOpenSSL() {
   if (!auth_tag_set_ && auth_tag_len_ != kNoAuthTagLength) {
-    if (!EVP_CIPHER_CTX_ctrl(ctx_.get(),
-                             EVP_CTRL_AEAD_SET_TAG,
+    if (!EVP_CIPHER_CTX_ctrl(ctx_,
+                             EVP_CTRL_CCM_SET_TAG,
                              auth_tag_len_,
                              reinterpret_cast<unsigned char*>(auth_tag_))) {
       return false;
@@ -3159,7 +3163,7 @@ bool CipherBase::SetAAD(const char* data, unsigned int len, int plaintext_len) {
   MarkPopErrorOnReturn mark_pop_error_on_return;
 
   int outlen;
-  const int mode = EVP_CIPHER_CTX_mode(ctx_.get());
+  const int mode = EVP_CIPHER_CTX_mode(ctx_);
 
   // When in CCM mode, we need to set the authentication tag and the plaintext
   // length in advance.
@@ -3178,11 +3182,11 @@ bool CipherBase::SetAAD(const char* data, unsigned int len, int plaintext_len) {
     }
 
     // Specify the plaintext length.
-    if (!EVP_CipherUpdate(ctx_.get(), nullptr, &outlen, nullptr, plaintext_len))
+    if (!EVP_CipherUpdate(ctx_, nullptr, &outlen, nullptr, plaintext_len))
       return false;
   }
 
-  return 1 == EVP_CipherUpdate(ctx_.get(),
+  return 1 == EVP_CipherUpdate(ctx_,
                                nullptr,
                                &outlen,
                                reinterpret_cast<const unsigned char*>(data),
@@ -3212,7 +3216,7 @@ CipherBase::UpdateResult CipherBase::Update(const char* data,
     return kErrorState;
   MarkPopErrorOnReturn mark_pop_error_on_return;
 
-  const int mode = EVP_CIPHER_CTX_mode(ctx_.get());
+  const int mode = EVP_CIPHER_CTX_mode(ctx_);
 
   if (mode == EVP_CIPH_CCM_MODE) {
     if (!CheckCCMMessageLength(len))
@@ -3226,11 +3230,11 @@ CipherBase::UpdateResult CipherBase::Update(const char* data,
   }
 
   *out_len = 0;
-  int buff_len = len + EVP_CIPHER_CTX_block_size(ctx_.get());
+  int buff_len = len + EVP_CIPHER_CTX_block_size(ctx_);
   // For key wrapping algorithms, get output size by calling
   // EVP_CipherUpdate() with null output.
   if (kind_ == kCipher && mode == EVP_CIPH_WRAP_MODE &&
-      EVP_CipherUpdate(ctx_.get(),
+      EVP_CipherUpdate(ctx_,
                        nullptr,
                        &buff_len,
                        reinterpret_cast<const unsigned char*>(data),
@@ -3239,7 +3243,7 @@ CipherBase::UpdateResult CipherBase::Update(const char* data,
   }
 
   *out = Malloc<unsigned char>(buff_len);
-  int r = EVP_CipherUpdate(ctx_.get(),
+  int r = EVP_CipherUpdate(ctx_,
                            *out,
                            out_len,
                            reinterpret_cast<const unsigned char*>(data),
@@ -3301,7 +3305,7 @@ bool CipherBase::SetAutoPadding(bool auto_padding) {
   if (!ctx_)
     return false;
   MarkPopErrorOnReturn mark_pop_error_on_return;
-  return EVP_CIPHER_CTX_set_padding(ctx_.get(), auto_padding);
+  return EVP_CIPHER_CTX_set_padding(ctx_, auto_padding);
 }
 
 
@@ -3318,10 +3322,10 @@ bool CipherBase::Final(unsigned char** out, int* out_len) {
   if (!ctx_)
     return false;
 
-  const int mode = EVP_CIPHER_CTX_mode(ctx_.get());
+  const int mode = EVP_CIPHER_CTX_mode(ctx_);
 
   *out = Malloc<unsigned char>(
-      static_cast<size_t>(EVP_CIPHER_CTX_block_size(ctx_.get())));
+      static_cast<size_t>(EVP_CIPHER_CTX_block_size(ctx_)));
 
   if (kind_ == kDecipher && IsSupportedAuthenticatedMode(mode)) {
     MaybePassAuthTagToOpenSSL();
@@ -3333,7 +3337,7 @@ bool CipherBase::Final(unsigned char** out, int* out_len) {
   if (kind_ == kDecipher && mode == EVP_CIPH_CCM_MODE) {
     ok = !pending_auth_failed_;
   } else {
-    ok = EVP_CipherFinal_ex(ctx_.get(), *out, out_len) == 1;
+    ok = EVP_CipherFinal_ex(ctx_, *out, out_len) == 1;
 
     if (ok && kind_ == kCipher && IsAuthenticatedMode()) {
       // In GCM mode, the authentication tag length can be specified in advance,
@@ -3351,7 +3355,8 @@ bool CipherBase::Final(unsigned char** out, int* out_len) {
     }
   }
 
-  ctx_.reset();
+  EVP_CIPHER_CTX_free(ctx_);
+  ctx_ = nullptr;
 
   return ok;
 }
@@ -3394,6 +3399,11 @@ void CipherBase::Final(const FunctionCallbackInfo<Value>& args) {
 }
 
 
+Hmac::~Hmac() {
+  HMAC_CTX_free(ctx_);
+}
+
+
 void Hmac::Initialize(Environment* env, v8::Local<Object> target) {
   Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
 
@@ -3423,9 +3433,16 @@ void Hmac::HmacInit(const char* hash_type, const char* key, int key_len) {
   if (key_len == 0) {
     key = "";
   }
+/*
   ctx_.reset(HMAC_CTX_new());
   if (!ctx_ || !HMAC_Init_ex(ctx_.get(), key, key_len, md, nullptr)) {
     ctx_.reset();
+*/
+  ctx_ = HMAC_CTX_new();
+  if (ctx_ == nullptr ||
+      !HMAC_Init_ex(ctx_, key, key_len, md, nullptr)) {
+    HMAC_CTX_free(ctx_);
+    ctx_ = nullptr;
     return ThrowCryptoError(env(), ERR_get_error());
   }
 }
@@ -3446,7 +3463,7 @@ void Hmac::HmacInit(const FunctionCallbackInfo<Value>& args) {
 bool Hmac::HmacUpdate(const char* data, int len) {
   if (!ctx_)
     return false;
-  int r = HMAC_Update(ctx_.get(),
+  int r = HMAC_Update(ctx_,
                       reinterpret_cast<const unsigned char*>(data),
                       len);
   return r == 1;
@@ -3493,10 +3510,17 @@ void Hmac::HmacDigest(const FunctionCallbackInfo<Value>& args) {
   unsigned char md_value[EVP_MAX_MD_SIZE];
   unsigned int md_len = 0;
 
+/*
   if (hmac->ctx_) {
     HMAC_Final(hmac->ctx_.get(), md_value, &md_len);
     hmac->ctx_.reset();
   }
+*/
+  if (hmac->ctx_ != nullptr) {
+    HMAC_Final(hmac->ctx_, md_value, &md_len);
+    HMAC_CTX_free(hmac->ctx_);
+    hmac->ctx_ = nullptr;
+  }
 
   Local<Value> error;
   MaybeLocal<Value> rc =
@@ -3514,6 +3538,11 @@ void Hmac::HmacDigest(const FunctionCallbackInfo<Value>& args) {
 }
 
 
+Hash::~Hash() {
+  EVP_MD_CTX_free(mdctx_);
+}
+
+
 void Hash::Initialize(Environment* env, v8::Local<Object> target) {
   Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
 
@@ -3543,9 +3572,16 @@ bool Hash::HashInit(const char* hash_type) {
   const EVP_MD* md = EVP_get_digestbyname(hash_type);
   if (md == nullptr)
     return false;
+/*
   mdctx_.reset(EVP_MD_CTX_new());
   if (!mdctx_ || EVP_DigestInit_ex(mdctx_.get(), md, nullptr) <= 0) {
     mdctx_.reset();
+*/
+  mdctx_ = EVP_MD_CTX_new();
+  if (mdctx_ == nullptr ||
+      EVP_DigestInit_ex(mdctx_, md, nullptr) <= 0) {
+    EVP_MD_CTX_free(mdctx_);
+    mdctx_ = nullptr;
     return false;
   }
   finalized_ = false;
@@ -3556,7 +3592,7 @@ bool Hash::HashInit(const char* hash_type) {
 bool Hash::HashUpdate(const char* data, int len) {
   if (!mdctx_)
     return false;
-  EVP_DigestUpdate(mdctx_.get(), data, len);
+  EVP_DigestUpdate(mdctx_, data, len);
   return true;
 }
 
@@ -3601,7 +3637,7 @@ void Hash::HashDigest(const FunctionCallbackInfo<Value>& args) {
   unsigned char md_value[EVP_MAX_MD_SIZE];
   unsigned int md_len;
 
-  EVP_DigestFinal_ex(hash->mdctx_.get(), md_value, &md_len);
+  EVP_DigestFinal_ex(hash->mdctx_, md_value, &md_len);
   hash->finalized_ = true;
 
   Local<Value> error;
@@ -3620,6 +3656,11 @@ void Hash::HashDigest(const FunctionCallbackInfo<Value>& args) {
 }
 
 
+SignBase::~SignBase() {
+  EVP_MD_CTX_free(mdctx_);
+}
+
+
 SignBase::Error SignBase::Init(const char* sign_type) {
   CHECK_NULL(mdctx_);
 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
@@ -3634,9 +3675,16 @@ SignBase::Error SignBase::Init(const char* sign_type) {
   if (md == nullptr)
     return kSignUnknownDigest;
 
+/*
   mdctx_.reset(EVP_MD_CTX_new());
   if (!mdctx_ || !EVP_DigestInit_ex(mdctx_.get(), md, nullptr)) {
     mdctx_.reset();
+*/
+  mdctx_ = EVP_MD_CTX_new();
+  if (mdctx_ == nullptr ||
+      !EVP_DigestInit_ex(mdctx_, md, nullptr)) {
+    EVP_MD_CTX_free(mdctx_);
+    mdctx_ = nullptr;
     return kSignInit;
   }
 
@@ -3647,7 +3695,7 @@ SignBase::Error SignBase::Init(const char* sign_type) {
 SignBase::Error SignBase::Update(const char* data, int len) {
   if (mdctx_ == nullptr)
     return kSignNotInitialised;
-  if (!EVP_DigestUpdate(mdctx_.get(), data, len))
+  if (!EVP_DigestUpdate(mdctx_, data, len))
     return kSignUpdate;
   return kSignOk;
 }
@@ -3749,7 +3797,8 @@ void Sign::SignUpdate(const FunctionCallbackInfo<Value>& args) {
   sign->CheckThrow(err);
 }
 
-static int Node_SignFinal(EVPMDPointer&& mdctx, unsigned char* md,
+// static int Node_SignFinal(EVPMDPointer&& mdctx, unsigned char* md,
+static int Node_SignFinal(EVP_MD_CTX* mdctx, unsigned char* md,
                           unsigned int* sig_len,
                           const EVPKeyPointer& pkey, int padding,
                           int pss_salt_len) {
@@ -3757,7 +3806,7 @@ static int Node_SignFinal(EVPMDPointer&& mdctx, unsigned char* md,
   unsigned int m_len;
 
   *sig_len = 0;
-  if (!EVP_DigestFinal_ex(mdctx.get(), m, &m_len))
+  if (!EVP_DigestFinal_ex(mdctx, m, &m_len))
     return 0;
 
   size_t sltmp = static_cast<size_t>(EVP_PKEY_size(pkey.get()));
@@ -3766,7 +3815,7 @@ static int Node_SignFinal(EVPMDPointer&& mdctx, unsigned char* md,
       EVP_PKEY_sign_init(pkctx.get()) > 0 &&
       ApplyRSAOptions(pkey, pkctx.get(), padding, pss_salt_len) &&
       EVP_PKEY_CTX_set_signature_md(pkctx.get(),
-                                    EVP_MD_CTX_md(mdctx.get())) > 0 &&
+                                    EVP_MD_CTX_md(mdctx)) > 0 &&
       EVP_PKEY_sign(pkctx.get(), md, &sltmp, m, m_len) > 0) {
     *sig_len = sltmp;
     return 1;
@@ -3784,7 +3833,8 @@ SignBase::Error Sign::SignFinal(const char* key_pem,
   if (!mdctx_)
     return kSignNotInitialised;
 
-  EVPMDPointer mdctx = std::move(mdctx_);
+  // EVPMDPointer mdctx = std::move(mdctx_);
+  EVP_MD_CTX* mdctx = std::move(mdctx_);
 
   BIOPointer bp(BIO_new_mem_buf(const_cast<char*>(key_pem), key_pem_len));
   if (!bp)
@@ -3967,12 +4017,12 @@ SignBase::Error Verify::VerifyFinal(const char* key_pem,
   unsigned int m_len;
   int r = 0;
   *verify_result = false;
-  EVPMDPointer mdctx = std::move(mdctx_);
+  EVP_MD_CTX* mdctx = std::move(mdctx_);
 
   if (ParsePublicKey(&pkey, key_pem, key_pem_len) != kParsePublicOk)
     return kSignPublicKey;
 
-  if (!EVP_DigestFinal_ex(mdctx.get(), m, &m_len))
+  if (!EVP_DigestFinal_ex(mdctx, m, &m_len))
     return kSignPublicKey;
 
   EVPKeyCtxPointer pkctx(EVP_PKEY_CTX_new(pkey.get(), nullptr));
@@ -3980,7 +4030,7 @@ SignBase::Error Verify::VerifyFinal(const char* key_pem,
       EVP_PKEY_verify_init(pkctx.get()) > 0 &&
       ApplyRSAOptions(pkey, pkctx.get(), padding, saltlen) &&
       EVP_PKEY_CTX_set_signature_md(pkctx.get(),
-                                    EVP_MD_CTX_md(mdctx.get())) > 0) {
+                                    EVP_MD_CTX_md(mdctx)) > 0) {
     r = EVP_PKEY_verify(pkctx.get(),
                         reinterpret_cast<const unsigned char*>(sig),
                         siglen,
@@ -4948,6 +4998,7 @@ inline void PBKDF2(const FunctionCallbackInfo<Value>& args) {
 }
 
 
+/*
 #ifndef OPENSSL_NO_SCRYPT
 struct ScryptJob : public CryptoJob {
   unsigned char* keybuf_data;
@@ -5038,6 +5089,7 @@ void Scrypt(const FunctionCallbackInfo<Value>& args) {
   args.GetReturnValue().Set(job->ToResult());
 }
 #endif  // OPENSSL_NO_SCRYPT
+*/
 
 
 void GetSSLCiphers(const FunctionCallbackInfo<Value>& args) {
@@ -5478,9 +5530,11 @@ void Initialize(Local<Object> target,
                  PublicKeyCipher::Cipher<PublicKeyCipher::kPublic,
                                          EVP_PKEY_verify_recover_init,
                                          EVP_PKEY_verify_recover>);
+/*
 #ifndef OPENSSL_NO_SCRYPT
   env->SetMethod(target, "scrypt", Scrypt);
 #endif  // OPENSSL_NO_SCRYPT
+*/
 }
 
 }  // namespace crypto
diff --git a/src/node_crypto.h b/src/node_crypto.h
index e850358..49eb078 100644
--- a/src/node_crypto.h
+++ b/src/node_crypto.h
@@ -81,7 +81,7 @@ using SSLSessionPointer = DeleteFnPtr<SSL_SESSION, SSL_SESSION_free>;
 using SSLPointer = DeleteFnPtr<SSL, SSL_free>;
 using EVPKeyPointer = DeleteFnPtr<EVP_PKEY, EVP_PKEY_free>;
 using EVPKeyCtxPointer = DeleteFnPtr<EVP_PKEY_CTX, EVP_PKEY_CTX_free>;
-using EVPMDPointer = DeleteFnPtr<EVP_MD_CTX, EVP_MD_CTX_free>;
+// using EVPMDPointer = DeleteFnPtr<EVP_MD_CTX, EVP_MD_CTX_free>;
 using RSAPointer = DeleteFnPtr<RSA, RSA_free>;
 using BignumPointer = DeleteFnPtr<BIGNUM, BN_free>;
 using NetscapeSPKIPointer = DeleteFnPtr<NETSCAPE_SPKI, NETSCAPE_SPKI_free>;
@@ -347,6 +347,10 @@ class SSLWrap {
 
 class CipherBase : public BaseObject {
  public:
+//  ~CipherBase() override {
+//    EVP_CIPHER_CTX_cleanup(ctx_);
+//  }
+
   static void Initialize(Environment* env, v8::Local<v8::Object> target);
 
   void MemoryInfo(MemoryTracker* tracker) const override {
@@ -413,7 +417,9 @@ class CipherBase : public BaseObject {
   }
 
  private:
-  DeleteFnPtr<EVP_CIPHER_CTX, EVP_CIPHER_CTX_free> ctx_;
+  EVP_CIPHER_CTX* ctx_;
+  // DeleteFnPtr<EVP_CIPHER_CTX, EVP_CIPHER_CTX_free> ctx_;
+  // DeleteFnPtr<EVP_CIPHER_CTX, EVP_CIPHER_CTX_cleanup> ctx_;
   const CipherKind kind_;
   bool auth_tag_set_;
   unsigned int auth_tag_len_;
@@ -424,6 +430,8 @@ class CipherBase : public BaseObject {
 
 class Hmac : public BaseObject {
  public:
+  ~Hmac() override;
+
   static void Initialize(Environment* env, v8::Local<v8::Object> target);
 
   void MemoryInfo(MemoryTracker* tracker) const override {
@@ -448,11 +456,14 @@ class Hmac : public BaseObject {
   }
 
  private:
-  DeleteFnPtr<HMAC_CTX, HMAC_CTX_free> ctx_;
+  // DeleteFnPtr<HMAC_CTX, HMAC_CTX_free> ctx_;
+  HMAC_CTX* ctx_;
 };
 
 class Hash : public BaseObject {
  public:
+  ~Hash() override;
+
   static void Initialize(Environment* env, v8::Local<v8::Object> target);
 
   void MemoryInfo(MemoryTracker* tracker) const override {
@@ -477,7 +488,8 @@ class Hash : public BaseObject {
   }
 
  private:
-  EVPMDPointer mdctx_;
+  // EVPMDPointer mdctx_;
+  EVP_MD_CTX* mdctx_;
   bool finalized_;
 };
 
@@ -494,9 +506,12 @@ class SignBase : public BaseObject {
   } Error;
 
   SignBase(Environment* env, v8::Local<v8::Object> wrap)
-      : BaseObject(env, wrap) {
+      : BaseObject(env, wrap),
+        mdctx_(nullptr) {
   }
 
+  ~SignBase() override;
+
   Error Init(const char* sign_type);
   Error Update(const char* data, int len);
 
@@ -509,7 +524,8 @@ class SignBase : public BaseObject {
  protected:
   void CheckThrow(Error error);
 
-  EVPMDPointer mdctx_;
+  // EVPMDPointer mdctx_;
+  EVP_MD_CTX* mdctx_;
 };
 
 class Sign : public SignBase {
diff --git a/test/parallel/test-crypto-authenticated.js b/test/parallel/test-crypto-authenticated.js
index 4b2d852..cb0bc41 100644
--- a/test/parallel/test-crypto-authenticated.js
+++ b/test/parallel/test-crypto-authenticated.js
@@ -99,7 +99,8 @@ for (const test of TEST_CASES) {
   const isOCB = /^aes-(128|192|256)-ocb$/.test(test.algo);
 
   let options;
-  if (isCCM || isOCB)
+  //if (isCCM || isOCB)
+  if (isCCM)
     options = { authTagLength: test.tag.length / 2 };
 
   const inputEncoding = test.plainIsHex ? 'hex' : 'ascii';
@@ -425,7 +426,8 @@ 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', 'ocb']) {
+  for (const mode of ['ccm']) {
     assert.throws(() => {
       crypto.createCipheriv(`aes-256-${mode}`,
                             'FxLKsqdmv0E9xrQhp0b1ZgI0K7JFZJM8',
-- 
1.8.3.1