[openssl-commits] [openssl] master update

Richard Levitte levitte at openssl.org
Mon Dec 7 16:45:42 UTC 2015


The branch master has been updated
       via  507db4c5313288d55eeb8434b0111201ba363b28 (commit)
       via  706e2462f1d2a884139334a5209664d5b8ca09ec (commit)
       via  716854d74e17e031257d184246cc59ed7fffb2cc (commit)
       via  25191fffb9f858b29b7029c7df944f25a4dc723f (commit)
       via  b3bb779997ae620918b8467cc6a452725013e204 (commit)
       via  a87a0a6e5eb7993ae7a4d2eb13e605d8b5428073 (commit)
       via  dc0099e1dd013abe52d0ff4901e02cca030bec97 (commit)
       via  e0a3a803d93dac94dfd8c7c54445be73f7572032 (commit)
       via  bfb0641f932490c2e7fb5f9f7cb4a88017a5abfa (commit)
       via  959ed5316c84d0e12ad18acfd40cefe15603ddfb (commit)
       via  67565323589932ef36e84d95b07bcc97325c9961 (commit)
       via  eda34e4bef33a3b8f1e207bf04769007c70cbd1e (commit)
       via  32fd54a9a36c172cf4e5fe4b7af2ae1f1ce1bc0a (commit)
       via  74cabf3fef77ab73c45e27cf6ed90f6db020e7c7 (commit)
       via  bf7c68177b6fbb80406c60136654b6fefe7e3ba2 (commit)
       via  3f43aecc599a5a729609deca7d98a677334ab3b8 (commit)
       via  ab0a14bbc7bc7cdda4cfb2b2a730804b3437429f (commit)
       via  cddcea8c4b46ea610d928af899e394d9e323c617 (commit)
       via  cc9d6655a1e6562564a0ac4b5dfcd72f24de7063 (commit)
       via  2db6bf6f856fc7a6e848e3c45b274b327a86784c (commit)
       via  6e59a892db781658c050e5217127c4147c116ac9 (commit)
       via  9b6c00707eae2cbce79479f4b1a5dc11019abca0 (commit)
       via  fa0c23de83efaf92da17cffce12444adbca48c89 (commit)
       via  77a01145be26ceeefa6870e1e9dd7f99ac123fa3 (commit)
       via  7638370ca6cb1d89eba5d891f522776b9da3d6e7 (commit)
      from  451a5bdf0386d7acf091c3e3b39107e5ed8be25d (commit)


- Log -----------------------------------------------------------------
commit 507db4c5313288d55eeb8434b0111201ba363b28
Author: Richard Levitte <levitte at openssl.org>
Date:   Tue Dec 1 03:28:22 2015 +0100

    Add an entry in CHANGES
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

commit 706e2462f1d2a884139334a5209664d5b8ca09ec
Author: Richard Levitte <levitte at openssl.org>
Date:   Fri Dec 4 13:04:54 2015 +0100

    Document EVP_MD constructors, destructors and manipulators
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

commit 716854d74e17e031257d184246cc59ed7fffb2cc
Author: Richard Levitte <levitte at openssl.org>
Date:   Mon Nov 30 23:43:59 2015 +0100

    Document the HMAC changes
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

commit 25191fffb9f858b29b7029c7df944f25a4dc723f
Author: Richard Levitte <levitte at openssl.org>
Date:   Tue Dec 1 03:19:11 2015 +0100

    Document the EVP_MD_CTX changes
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

commit b3bb779997ae620918b8467cc6a452725013e204
Author: Richard Levitte <levitte at openssl.org>
Date:   Fri Nov 27 14:47:08 2015 +0100

    make update
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

commit a87a0a6e5eb7993ae7a4d2eb13e605d8b5428073
Author: Richard Levitte <levitte at openssl.org>
Date:   Wed Dec 2 22:49:24 2015 +0100

    Cleanup: fix all sources that used HMAC_CTX_init
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

commit dc0099e1dd013abe52d0ff4901e02cca030bec97
Author: Richard Levitte <levitte at openssl.org>
Date:   Wed Dec 2 22:47:31 2015 +0100

    Cleanup: rename HMAC_CTX_init to HMAC_CTX_reset
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

commit e0a3a803d93dac94dfd8c7c54445be73f7572032
Author: Richard Levitte <levitte at openssl.org>
Date:   Wed Dec 2 00:52:56 2015 +0100

    Cleanup: support EVP_MD_CTX_(create|init|destroy) for deprecated use
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

commit bfb0641f932490c2e7fb5f9f7cb4a88017a5abfa
Author: Richard Levitte <levitte at openssl.org>
Date:   Wed Dec 2 00:49:35 2015 +0100

    Cleanup: fix all sources that used EVP_MD_CTX_(create|init|destroy)
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

commit 959ed5316c84d0e12ad18acfd40cefe15603ddfb
Author: Richard Levitte <levitte at openssl.org>
Date:   Wed Dec 2 00:26:19 2015 +0100

    Cleanup: rename EVP_MD_CTX_(create|init|destroy) to EVP_MD_CTX_(new|reset|free)
    
    Looking over names, it seems like we usually use names ending with
    _new and _free as object constructors and destructors.  Also, since
    EVP_MD_CTX_init is now used to reset a EVP_MD_CTX, it might as well be
    named accordingly.
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

commit 67565323589932ef36e84d95b07bcc97325c9961
Author: Richard Levitte <levitte at openssl.org>
Date:   Wed Dec 2 00:22:30 2015 +0100

    Cleanup: Remove M_EVP_MD_* macros
    
    These macros were only meant for crypto/evp, and are now entirely
    unused.
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

commit eda34e4bef33a3b8f1e207bf04769007c70cbd1e
Author: Richard Levitte <levitte at openssl.org>
Date:   Mon Nov 30 23:43:27 2015 +0100

    Adapt the rest of the source to the removal of (EVP_MD_CTX|HMAC_CTX)_cleanup
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

commit 32fd54a9a36c172cf4e5fe4b7af2ae1f1ce1bc0a
Author: Richard Levitte <levitte at openssl.org>
Date:   Mon Nov 30 23:42:39 2015 +0100

    Remove HMAC_CTX_cleanup and combine its functionality into EVP_MD_CTX_init
    
    This follows the same idea as the combination of EVP_MD_CTX_cleanup
    and EVP_MD_CTX_init into one function.
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

commit 74cabf3fef77ab73c45e27cf6ed90f6db020e7c7
Author: Richard Levitte <levitte at openssl.org>
Date:   Tue Dec 1 01:38:35 2015 +0100

    Remove EVP_MD_CTX_cleanup and put its functionality into EVP_MD_CTX_init
    
    The idea is that with EVP_MD_CTX_create() and EVP_MD_CTX_destroy(),
    EVP_MD_CTX_cleanup and EVP_MD_CTX_init is not used the same as before.
    Instead, we need a single function that can be used to reinitialise an
    existing EVP_MD_CTX that's been created with EVP_MD_CTX_create()
    previously.  Combining EVP_MD_CTX_cleanup and EVP_MD_CTX_init into
    that one function is the answer.
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

commit bf7c68177b6fbb80406c60136654b6fefe7e3ba2
Author: Richard Levitte <levitte at openssl.org>
Date:   Mon Nov 30 13:44:28 2015 +0100

    Adapt the rest of the source to the opaque HMAC_CTX
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

commit 3f43aecc599a5a729609deca7d98a677334ab3b8
Author: Richard Levitte <levitte at openssl.org>
Date:   Mon Nov 30 13:34:20 2015 +0100

    Make the definition of HMAC_CTX opaque
    
    This moves the definition to crypto/hmac/hmac_lcl.h.  Constructor and
    destructor added, and the typedef moved to include/openssl/ossl_typ.h.
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

commit ab0a14bbc7bc7cdda4cfb2b2a730804b3437429f
Author: Richard Levitte <levitte at openssl.org>
Date:   Mon Nov 30 10:25:36 2015 +0100

    Add inclusion of internal/evp_int.h to all crypto/ files that need it
    
    These are the files that add new EVP_MDs.
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

commit cddcea8c4b46ea610d928af899e394d9e323c617
Author: Richard Levitte <levitte at openssl.org>
Date:   Mon Nov 30 10:24:12 2015 +0100

    Adapt all engines that add new EVP_MDs
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

commit cc9d6655a1e6562564a0ac4b5dfcd72f24de7063
Author: Richard Levitte <levitte at openssl.org>
Date:   Sun Nov 29 20:12:35 2015 +0100

    Have the few apps that accessed EVP_MD directly use accessors instead
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

commit 2db6bf6f856fc7a6e848e3c45b274b327a86784c
Author: Richard Levitte <levitte at openssl.org>
Date:   Sun Nov 29 20:09:34 2015 +0100

    Make the definition of EVP_MD opaque
    
    This moves the definition to crypto/include/internal/evp_int.h and
    defines all the necessary method creators, destructors, writers and
    accessors.  The name standard for the latter is inspired from the
    corresponding functions to manipulate UI methods.
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

commit 6e59a892db781658c050e5217127c4147c116ac9
Author: Richard Levitte <levitte at openssl.org>
Date:   Fri Nov 27 14:02:12 2015 +0100

    Adjust all accesses to EVP_MD_CTX to use accessor functions.
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

commit 9b6c00707eae2cbce79479f4b1a5dc11019abca0
Author: Richard Levitte <levitte at openssl.org>
Date:   Fri Nov 27 14:19:27 2015 +0100

    Document the changed HMAC API.
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

commit fa0c23de83efaf92da17cffce12444adbca48c89
Author: Richard Levitte <levitte at openssl.org>
Date:   Fri Nov 27 14:10:15 2015 +0100

    Adapt HMAC to the EVP_MD_CTX changes
    
    This change required some special treatment, as HMAC is intertwined
    with EVP_MD.  For now, all local HMAC_CTX variables MUST be
    initialised with HMAC_CTX_EMPTY, or whatever happens to be on the
    stack will be mistaken for actual pointers to EVP_MD_CTX.  This will
    change as soon as HMAC_CTX becomes opaque.
    
    Also, since HMAC_CTX_init() can fail now, its return type changes from
    void to int, and it will return 0 on failure, 1 on success.
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

commit 77a01145be26ceeefa6870e1e9dd7f99ac123fa3
Author: Richard Levitte <levitte at openssl.org>
Date:   Fri Nov 27 14:17:50 2015 +0100

    Have other crypto/evp files include evp_locl.h
    
    Note: this does not include the files in crypto/evp that are just
    instanciations of EVP_MD.
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

commit 7638370ca6cb1d89eba5d891f522776b9da3d6e7
Author: Richard Levitte <levitte at openssl.org>
Date:   Fri Nov 27 13:35:02 2015 +0100

    Make the definition of EVP_MD_CTX opaque
    
    This moves the definitionto crypto/evp/evp_locl.h, along with a few
    associated accessor macros.  A few accessor/writer functions added.
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

-----------------------------------------------------------------------

Summary of changes:
 CHANGES                                          |  22 +++
 apps/ca.c                                        |   2 +-
 apps/passwd.c                                    |  58 +++---
 apps/req.c                                       |  44 +++--
 apps/speed.c                                     |  20 +-
 apps/ts.c                                        |  13 +-
 crypto/asn1/Makefile                             |   8 +-
 crypto/asn1/a_sign.c                             |  34 ++--
 crypto/asn1/a_verify.c                           |  33 ++--
 crypto/asn1/asn_mime.c                           |   1 +
 crypto/asn1/x_algor.c                            |   1 +
 crypto/cmac/cm_pmeth.c                           |   4 +-
 crypto/cms/cms_asn1.c                            |   3 +-
 crypto/cms/cms_dd.c                              |  14 +-
 crypto/cms/cms_lcl.h                             |   2 +-
 crypto/cms/cms_sd.c                              |  61 +++---
 crypto/dh/dh_kdf.c                               |  18 +-
 crypto/dsa/dsa_gen.c                             |  19 +-
 crypto/ecdh/ech_kdf.c                            |  20 +-
 crypto/engine/eng_openssl.c                      |  98 ++++++---
 crypto/evp/Makefile                              |  35 ++--
 crypto/evp/bio_md.c                              |   6 +-
 crypto/evp/bio_ok.c                              |  74 ++++---
 crypto/evp/digest.c                              | 104 +++++-----
 crypto/evp/evp_key.c                             |  24 +--
 crypto/evp/evp_lib.c                             | 147 ++++++++++++++
 crypto/evp/evp_locl.h                            |  14 ++
 crypto/evp/m_md4.c                               |   7 +-
 crypto/evp/m_md5.c                               |   7 +-
 crypto/evp/m_md5_sha1.c                          |   9 +-
 crypto/evp/m_mdc2.c                              |   7 +-
 crypto/evp/m_null.c                              |   1 +
 crypto/evp/m_ripemd.c                            |   7 +-
 crypto/evp/m_sha1.c                              |  25 +--
 crypto/evp/m_sigver.c                            |  27 ++-
 crypto/evp/m_wp.c                                |   7 +-
 crypto/evp/names.c                               |   1 +
 crypto/evp/p5_crpt.c                             |  25 ++-
 crypto/evp/p5_crpt2.c                            |  50 +++--
 crypto/evp/p_sign.c                              |  22 ++-
 crypto/evp/p_verify.c                            |  18 +-
 crypto/hmac/Makefile                             |   1 +
 crypto/hmac/hm_pmeth.c                           |  29 +--
 crypto/hmac/hmac.c                               | 129 ++++++++----
 include/openssl/ssl2.h => crypto/hmac/hmac_lcl.h |  24 ++-
 crypto/include/internal/evp_int.h                |  17 ++
 crypto/pem/pem_seal.c                            |  10 +-
 crypto/pem/pvkfmt.c                              |  14 +-
 crypto/pkcs12/p12_key.c                          |  23 ++-
 crypto/pkcs12/p12_mutl.c                         |  16 +-
 crypto/pkcs7/pk7_doit.c                          |  58 +++---
 crypto/rand/md_rand.c                            |  72 ++++---
 crypto/rsa/rsa_ameth.c                           |   2 +-
 crypto/rsa/rsa_oaep.c                            |  19 +-
 crypto/rsa/rsa_pss.c                             |  41 ++--
 crypto/srp/srp_lib.c                             |  89 +++++----
 crypto/srp/srp_vfy.c                             |  22 ++-
 crypto/ts/ts_rsp_verify.c                        |  15 +-
 crypto/x509/x509_cmp.c                           |  31 +--
 doc/crypto/EVP_DigestInit.pod                    |  70 +++----
 doc/crypto/EVP_DigestSignInit.pod                |   4 +-
 doc/crypto/EVP_DigestVerifyInit.pod              |   4 +-
 doc/crypto/EVP_MD_meth_new.pod                   | 160 +++++++++++++++
 doc/crypto/EVP_SignInit.pod                      |   4 +-
 doc/crypto/EVP_VerifyInit.pod                    |   4 +-
 doc/crypto/hmac.pod                              |  39 ++--
 engines/ccgost/gost_crypt.c                      |  60 ++++--
 engines/ccgost/gost_eng.c                        |  34 +++-
 engines/ccgost/gost_lcl.h                        |   6 +-
 engines/ccgost/gost_md.c                         |  59 +++---
 engines/ccgost/gost_pmeth.c                      |   3 +-
 engines/e_dasync.c                               |  67 +++++--
 engines/e_ossltest.c                             | 240 +++++++++++++++--------
 include/openssl/evp.h                            |  90 +++++----
 include/openssl/hmac.h                           |  17 +-
 include/openssl/ossl_typ.h                       |   2 +
 include/openssl/pem.h                            |   2 +-
 ssl/record/ssl3_record.c                         |  53 ++---
 ssl/s3_cbc.c                                     |  24 +--
 ssl/s3_enc.c                                     | 100 ++++++----
 ssl/ssl_lib.c                                    |  20 +-
 ssl/statem/statem_clnt.c                         |  49 +++--
 ssl/statem/statem_dtls.c                         |   3 +-
 ssl/statem/statem_srvr.c                         |  58 +++---
 ssl/t1_enc.c                                     |  58 +++---
 ssl/t1_lib.c                                     |  21 +-
 test/ecdsatest.c                                 |  14 +-
 test/evp_extra_test.c                            |  38 ++--
 test/evp_test.c                                  |  10 +-
 test/gost2814789test.c                           |  21 +-
 test/hmactest.c                                  |  66 ++++---
 test/mdc2test.c                                  |  20 +-
 test/sha1test.c                                  |  12 +-
 test/sha256t.c                                   |  26 +--
 test/sha512t.c                                   |  26 +--
 util/libeay.num                                  |  42 +++-
 96 files changed, 2062 insertions(+), 1168 deletions(-)
 copy include/openssl/ssl2.h => crypto/hmac/hmac_lcl.h (90%)
 create mode 100644 doc/crypto/EVP_MD_meth_new.pod

diff --git a/CHANGES b/CHANGES
index db3f638..9ee1731 100644
--- a/CHANGES
+++ b/CHANGES
@@ -9,6 +9,28 @@
      exchange. The LOW ciphers currently doesn't have any ciphers in it.
      [Kurt Roeckx]
 
+  *) Make EVP_MD_CTX, EVP_MD and HMAC_CTX opaque.  For HMAC_CTX, the
+     following constructors and destructors were added:
+
+        HMAC_CTX *HMAC_CTX_new(void);
+        void HMAC_CTX_free(HMAC_CTX *ctx);
+
+     For EVP_MD, a complete API to create, fill and destroy such
+     methods has been added.  See EVP_MD_meth_new(3) for
+     documentation.
+
+     Additional changes:
+     1) HMAC_CTX_cleanup() and EVP_MD_CTX_cleanup() were removed,
+        HMAC_CTX_init() and EVP_MD_CTX_init() should be called instead
+        to reinitialise and already created structure.  Also,
+        HMAC_CTX_init() and EVP_MD_CTX_init() now return 0 for failure
+        and 1 for success (they previously had the return type void).
+     2) For consistency with the majority of our object creators and
+        destructors, EVP_MD_CTX_(create|destroy) were renamed to
+        EVP_MD_CTX_(new|free).  The old names are retained as macros
+        for deprecated builds.
+     [Richard Levitte]
+
   *) Added ASYNC support. Libcrypto now includes the async sub-library to enable
      cryptographic operations to be performed asynchronously as long as an
      asynchronous capable engine is used. See the ASYNC_start_job() man page for
diff --git a/apps/ca.c b/apps/ca.c
index eea9d99..f6ba239 100644
--- a/apps/ca.c
+++ b/apps/ca.c
@@ -828,7 +828,7 @@ end_of_options:
         }
         if (verbose)
             BIO_printf(bio_err, "message digest is %s\n",
-                       OBJ_nid2ln(dgst->type));
+                       OBJ_nid2ln(EVP_MD_type(dgst)));
         if ((policy == NULL) && ((policy = NCONF_get_string(conf,
                                                             section,
                                                             ENV_POLICY)) ==
diff --git a/apps/passwd.c b/apps/passwd.c
index 372e0e8..2a32111 100644
--- a/apps/passwd.c
+++ b/apps/passwd.c
@@ -307,7 +307,7 @@ static char *md5crypt(const char *passwd, const char *magic, const char *salt)
     char *salt_out;
     int n;
     unsigned int i;
-    EVP_MD_CTX md, md2;
+    EVP_MD_CTX *md, *md2;
     size_t passwd_len, salt_len;
 
     passwd_len = strlen(passwd);
@@ -322,45 +322,50 @@ static char *md5crypt(const char *passwd, const char *magic, const char *salt)
     salt_len = strlen(salt_out);
     assert(salt_len <= 8);
 
-    EVP_MD_CTX_init(&md);
-    EVP_DigestInit_ex(&md, EVP_md5(), NULL);
-    EVP_DigestUpdate(&md, passwd, passwd_len);
-    EVP_DigestUpdate(&md, "$", 1);
-    EVP_DigestUpdate(&md, magic, strlen(magic));
-    EVP_DigestUpdate(&md, "$", 1);
-    EVP_DigestUpdate(&md, salt_out, salt_len);
-
-    EVP_MD_CTX_init(&md2);
-    EVP_DigestInit_ex(&md2, EVP_md5(), NULL);
-    EVP_DigestUpdate(&md2, passwd, passwd_len);
-    EVP_DigestUpdate(&md2, salt_out, salt_len);
-    EVP_DigestUpdate(&md2, passwd, passwd_len);
-    EVP_DigestFinal_ex(&md2, buf, NULL);
+    md = EVP_MD_CTX_new();
+    if (md == NULL)
+        return NULL;
+    EVP_DigestInit_ex(md, EVP_md5(), NULL);
+    EVP_DigestUpdate(md, passwd, passwd_len);
+    EVP_DigestUpdate(md, "$", 1);
+    EVP_DigestUpdate(md, magic, strlen(magic));
+    EVP_DigestUpdate(md, "$", 1);
+    EVP_DigestUpdate(md, salt_out, salt_len);
+
+    md2 = EVP_MD_CTX_new();
+    if (md2 == NULL)
+        return NULL;
+    EVP_DigestInit_ex(md2, EVP_md5(), NULL);
+    EVP_DigestUpdate(md2, passwd, passwd_len);
+    EVP_DigestUpdate(md2, salt_out, salt_len);
+    EVP_DigestUpdate(md2, passwd, passwd_len);
+    EVP_DigestFinal_ex(md2, buf, NULL);
 
     for (i = passwd_len; i > sizeof buf; i -= sizeof buf)
-        EVP_DigestUpdate(&md, buf, sizeof buf);
-    EVP_DigestUpdate(&md, buf, i);
+        EVP_DigestUpdate(md, buf, sizeof buf);
+    EVP_DigestUpdate(md, buf, i);
 
     n = passwd_len;
     while (n) {
-        EVP_DigestUpdate(&md, (n & 1) ? "\0" : passwd, 1);
+        EVP_DigestUpdate(md, (n & 1) ? "\0" : passwd, 1);
         n >>= 1;
     }
-    EVP_DigestFinal_ex(&md, buf, NULL);
+    EVP_DigestFinal_ex(md, buf, NULL);
 
     for (i = 0; i < 1000; i++) {
-        EVP_DigestInit_ex(&md2, EVP_md5(), NULL);
-        EVP_DigestUpdate(&md2, (i & 1) ? (unsigned const char *)passwd : buf,
+        EVP_DigestInit_ex(md2, EVP_md5(), NULL);
+        EVP_DigestUpdate(md2, (i & 1) ? (unsigned const char *)passwd : buf,
                          (i & 1) ? passwd_len : sizeof buf);
         if (i % 3)
-            EVP_DigestUpdate(&md2, salt_out, salt_len);
+            EVP_DigestUpdate(md2, salt_out, salt_len);
         if (i % 7)
-            EVP_DigestUpdate(&md2, passwd, passwd_len);
-        EVP_DigestUpdate(&md2, (i & 1) ? buf : (unsigned const char *)passwd,
+            EVP_DigestUpdate(md2, passwd, passwd_len);
+        EVP_DigestUpdate(md2, (i & 1) ? buf : (unsigned const char *)passwd,
                          (i & 1) ? sizeof buf : passwd_len);
-        EVP_DigestFinal_ex(&md2, buf, NULL);
+        EVP_DigestFinal_ex(md2, buf, NULL);
     }
-    EVP_MD_CTX_cleanup(&md2);
+    EVP_MD_CTX_free(md2);
+    EVP_MD_CTX_free(md);
 
     {
         /* transform buf into output string */
@@ -399,7 +404,6 @@ static char *md5crypt(const char *passwd, const char *magic, const char *salt)
         *output = 0;
         assert(strlen(out_buf) < sizeof(out_buf));
     }
-    EVP_MD_CTX_cleanup(&md);
 
     return out_buf;
 }
diff --git a/apps/req.c b/apps/req.c
index 5d9231c..c275763 100644
--- a/apps/req.c
+++ b/apps/req.c
@@ -1492,7 +1492,8 @@ static int do_sign_init(EVP_MD_CTX *ctx, EVP_PKEY *pkey,
     EVP_PKEY_CTX *pkctx = NULL;
     int i;
 
-    EVP_MD_CTX_init(ctx);
+    if (ctx == NULL)
+        return 0;
     if (!EVP_DigestSignInit(ctx, &pkctx, md, NULL, pkey))
         return 0;
     for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) {
@@ -1510,13 +1511,16 @@ int do_X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md,
                  STACK_OF(OPENSSL_STRING) *sigopts)
 {
     int rv;
-    EVP_MD_CTX mctx;
+    EVP_MD_CTX *mctx = EVP_MD_CTX_new();
 
-    EVP_MD_CTX_init(&mctx);
-    rv = do_sign_init(&mctx, pkey, md, sigopts);
+    rv = do_sign_init(mctx, pkey, md, sigopts);
+    /* Note: X509_sign_ctx() calls ASN1_item_sign_ctx(), which destroys
+     * the EVP_MD_CTX we send it, so only destroy it here if the former
+     * isn't called */
     if (rv > 0)
-        rv = X509_sign_ctx(x, &mctx);
-    EVP_MD_CTX_cleanup(&mctx);
+        rv = X509_sign_ctx(x, mctx);
+    else
+        EVP_MD_CTX_free(mctx);
     return rv > 0 ? 1 : 0;
 }
 
@@ -1524,13 +1528,15 @@ int do_X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md,
                      STACK_OF(OPENSSL_STRING) *sigopts)
 {
     int rv;
-    EVP_MD_CTX mctx;
-
-    EVP_MD_CTX_init(&mctx);
-    rv = do_sign_init(&mctx, pkey, md, sigopts);
+    EVP_MD_CTX *mctx = EVP_MD_CTX_new();
+    rv = do_sign_init(mctx, pkey, md, sigopts);
+    /* Note: X509_REQ_sign_ctx() calls ASN1_item_sign_ctx(), which destroys
+     * the EVP_MD_CTX we send it, so only destroy it here if the former
+     * isn't called */
     if (rv > 0)
-        rv = X509_REQ_sign_ctx(x, &mctx);
-    EVP_MD_CTX_cleanup(&mctx);
+        rv = X509_REQ_sign_ctx(x, mctx);
+    else
+        EVP_MD_CTX_free(mctx);
     return rv > 0 ? 1 : 0;
 }
 
@@ -1538,12 +1544,14 @@ int do_X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md,
                      STACK_OF(OPENSSL_STRING) *sigopts)
 {
     int rv;
-    EVP_MD_CTX mctx;
-
-    EVP_MD_CTX_init(&mctx);
-    rv = do_sign_init(&mctx, pkey, md, sigopts);
+    EVP_MD_CTX *mctx = EVP_MD_CTX_new();
+    rv = do_sign_init(mctx, pkey, md, sigopts);
+    /* Note: X509_CRL_sign_ctx() calls ASN1_item_sign_ctx(), which destroys
+     * the EVP_MD_CTX we send it, so only destroy it here if the former
+     * isn't called */
     if (rv > 0)
-        rv = X509_CRL_sign_ctx(x, &mctx);
-    EVP_MD_CTX_cleanup(&mctx);
+        rv = X509_CRL_sign_ctx(x, mctx);
+    else
+        EVP_MD_CTX_free(mctx);
     return rv > 0 ? 1 : 0;
 }
diff --git a/apps/speed.c b/apps/speed.c
index 68530b1..8e1fe84 100644
--- a/apps/speed.c
+++ b/apps/speed.c
@@ -1298,24 +1298,28 @@ int speed_main(int argc, char **argv)
 
 #if !defined(OPENSSL_NO_MD5)
     if (doit[D_HMAC]) {
-        HMAC_CTX hctx;
+        HMAC_CTX *hctx = NULL;
 
-        HMAC_CTX_init(&hctx);
-        HMAC_Init_ex(&hctx, (unsigned char *)"This is a key...",
+        hctx = HMAC_CTX_new();
+        if (hctx == NULL) {
+            BIO_printf(bio_err, "HMAC malloc failure, exiting...");
+            exit(1);
+        }
+        HMAC_Init_ex(hctx, (unsigned char *)"This is a key...",
                      16, EVP_md5(), NULL);
 
         for (j = 0; j < SIZE_NUM; j++) {
             print_message(names[D_HMAC], c[D_HMAC][j], lengths[j]);
             Time_F(START);
             for (count = 0, run = 1; COND(c[D_HMAC][j]); count++) {
-                HMAC_Init_ex(&hctx, NULL, 0, NULL, NULL);
-                HMAC_Update(&hctx, buf, lengths[j]);
-                HMAC_Final(&hctx, &(hmac[0]), NULL);
+                HMAC_Init_ex(hctx, NULL, 0, NULL, NULL);
+                HMAC_Update(hctx, buf, lengths[j]);
+                HMAC_Final(hctx, &(hmac[0]), NULL);
             }
             d = Time_F(STOP);
             print_result(D_HMAC, j, count, d);
         }
-        HMAC_CTX_cleanup(&hctx);
+        HMAC_CTX_free(hctx);
     }
 #endif
     if (doit[D_SHA1]) {
@@ -1687,7 +1691,7 @@ int speed_main(int argc, char **argv)
                 EVP_CIPHER_CTX_cleanup(&ctx);
             }
             if (evp_md) {
-                names[D_EVP] = OBJ_nid2ln(evp_md->type);
+                names[D_EVP] = OBJ_nid2ln(EVP_MD_type(evp_md));
                 print_message(names[D_EVP], save_count, lengths[j]);
 
                 Time_F(START);
diff --git a/apps/ts.c b/apps/ts.c
index ac91323..00b5e53 100644
--- a/apps/ts.c
+++ b/apps/ts.c
@@ -523,17 +523,22 @@ static int create_digest(BIO *input, char *digest, const EVP_MD *md,
         return 0;
 
     if (input) {
-        EVP_MD_CTX md_ctx;
+        EVP_MD_CTX *md_ctx = EVP_MD_CTX_new();
         unsigned char buffer[4096];
         int length;
 
+        if (md_ctx == NULL)
+            return 0;
         *md_value = app_malloc(md_value_len, "digest buffer");
-        EVP_DigestInit(&md_ctx, md);
+        EVP_DigestInit(md_ctx, md);
         while ((length = BIO_read(input, buffer, sizeof(buffer))) > 0) {
-            EVP_DigestUpdate(&md_ctx, buffer, length);
+            EVP_DigestUpdate(md_ctx, buffer, length);
         }
-        if (!EVP_DigestFinal(&md_ctx, *md_value, NULL))
+        if (!EVP_DigestFinal(md_ctx, *md_value, NULL)) {
+            EVP_MD_CTX_free(md_ctx);
             return 0;
+        }
+        EVP_MD_CTX_free(md_ctx);
     } else {
         long digest_len;
         *md_value = string_to_hex(digest, &digest_len);
diff --git a/crypto/asn1/Makefile b/crypto/asn1/Makefile
index a6f1bac..3f59adc 100644
--- a/crypto/asn1/Makefile
+++ b/crypto/asn1/Makefile
@@ -208,7 +208,7 @@ a_sign.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
 a_sign.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
 a_sign.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
 a_sign.o: ../include/internal/asn1_int.h ../include/internal/cryptlib.h
-a_sign.o: a_sign.c
+a_sign.o: ../include/internal/evp_int.h a_sign.c
 a_strex.o: ../../e_os.h ../../include/openssl/asn1.h
 a_strex.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 a_strex.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
@@ -349,7 +349,8 @@ asn_mime.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
 asn_mime.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
 asn_mime.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
 asn_mime.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-asn_mime.o: ../include/internal/cryptlib.h asn1_locl.h asn_mime.c
+asn_mime.o: ../include/internal/cryptlib.h ../include/internal/evp_int.h
+asn_mime.o: asn1_locl.h asn_mime.c
 asn_moid.o: ../../e_os.h ../../include/openssl/asn1.h
 asn_moid.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 asn_moid.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
@@ -689,7 +690,8 @@ x_algor.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 x_algor.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 x_algor.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
 x_algor.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-x_algor.o: ../../include/openssl/x509_vfy.h x_algor.c
+x_algor.o: ../../include/openssl/x509_vfy.h ../include/internal/evp_int.h
+x_algor.o: x_algor.c
 x_bignum.o: ../../e_os.h ../../include/openssl/asn1.h
 x_bignum.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
 x_bignum.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
diff --git a/crypto/asn1/a_sign.c b/crypto/asn1/a_sign.c
index 18923b1..5b5d5b7 100644
--- a/crypto/asn1/a_sign.c
+++ b/crypto/asn1/a_sign.c
@@ -124,6 +124,7 @@
 #include <openssl/objects.h>
 #include <openssl/buffer.h>
 #include "internal/asn1_int.h"
+#include "internal/evp_int.h"
 
 #ifndef NO_ASN1_OLD
 
@@ -131,12 +132,15 @@ int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, X509_ALGOR *algor2,
               ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey,
               const EVP_MD *type)
 {
-    EVP_MD_CTX ctx;
+    EVP_MD_CTX *ctx = EVP_MD_CTX_new();
     unsigned char *p, *buf_in = NULL, *buf_out = NULL;
     int i, inl = 0, outl = 0, outll = 0;
     X509_ALGOR *a;
 
-    EVP_MD_CTX_init(&ctx);
+    if (ctx == NULL) {
+        ASN1err(ASN1_F_ASN1_SIGN, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
     for (i = 0; i < 2; i++) {
         if (i == 0)
             a = algor1;
@@ -182,9 +186,9 @@ int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, X509_ALGOR *algor2,
     p = buf_in;
 
     i2d(data, &p);
-    if (!EVP_SignInit_ex(&ctx, type, NULL)
-        || !EVP_SignUpdate(&ctx, (unsigned char *)buf_in, inl)
-        || !EVP_SignFinal(&ctx, (unsigned char *)buf_out,
+    if (!EVP_SignInit_ex(ctx, type, NULL)
+        || !EVP_SignUpdate(ctx, (unsigned char *)buf_in, inl)
+        || !EVP_SignFinal(ctx, (unsigned char *)buf_out,
                           (unsigned int *)&outl, pkey)) {
         outl = 0;
         ASN1err(ASN1_F_ASN1_SIGN, ERR_R_EVP_LIB);
@@ -201,7 +205,7 @@ int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, X509_ALGOR *algor2,
     signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
     signature->flags |= ASN1_STRING_FLAG_BITS_LEFT;
  err:
-    EVP_MD_CTX_cleanup(&ctx);
+    EVP_MD_CTX_free(ctx);
     OPENSSL_clear_free((char *)buf_in, (unsigned int)inl);
     OPENSSL_clear_free((char *)buf_out, outll);
     return (outl);
@@ -213,13 +217,17 @@ int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1,
                    X509_ALGOR *algor2, ASN1_BIT_STRING *signature, void *asn,
                    EVP_PKEY *pkey, const EVP_MD *type)
 {
-    EVP_MD_CTX ctx;
-    EVP_MD_CTX_init(&ctx);
-    if (!EVP_DigestSignInit(&ctx, NULL, type, NULL, pkey)) {
-        EVP_MD_CTX_cleanup(&ctx);
+    EVP_MD_CTX *ctx = EVP_MD_CTX_new();
+
+    if (ctx == NULL) {
+        ASN1err(ASN1_F_ASN1_ITEM_SIGN, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    if (!EVP_DigestSignInit(ctx, NULL, type, NULL, pkey)) {
+        EVP_MD_CTX_free(ctx);
         return 0;
     }
-    return ASN1_item_sign_ctx(it, algor1, algor2, signature, asn, &ctx);
+    return ASN1_item_sign_ctx(it, algor1, algor2, signature, asn, ctx);
 }
 
 int ASN1_item_sign_ctx(const ASN1_ITEM *it,
@@ -234,7 +242,7 @@ int ASN1_item_sign_ctx(const ASN1_ITEM *it,
     int rv;
 
     type = EVP_MD_CTX_md(ctx);
-    pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx);
+    pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_pkey_ctx(ctx));
 
     if (!type || !pkey) {
         ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ASN1_R_CONTEXT_NOT_INITIALISED);
@@ -307,7 +315,7 @@ int ASN1_item_sign_ctx(const ASN1_ITEM *it,
     signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
     signature->flags |= ASN1_STRING_FLAG_BITS_LEFT;
  err:
-    EVP_MD_CTX_cleanup(ctx);
+    EVP_MD_CTX_free(ctx);
     OPENSSL_clear_free((char *)buf_in, (unsigned int)inl);
     OPENSSL_clear_free((char *)buf_out, outll);
     return (outl);
diff --git a/crypto/asn1/a_verify.c b/crypto/asn1/a_verify.c
index 540b71c..4acee3e 100644
--- a/crypto/asn1/a_verify.c
+++ b/crypto/asn1/a_verify.c
@@ -77,12 +77,15 @@
 int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a, ASN1_BIT_STRING *signature,
                 char *data, EVP_PKEY *pkey)
 {
-    EVP_MD_CTX ctx;
+    EVP_MD_CTX *ctx = EVP_MD_CTX_new();
     const EVP_MD *type;
     unsigned char *p, *buf_in = NULL;
     int ret = -1, i, inl;
 
-    EVP_MD_CTX_init(&ctx);
+    if (ctx == NULL) {
+        ASN1err(ASN1_F_ASN1_VERIFY, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
     i = OBJ_obj2nid(a->algorithm);
     type = EVP_get_digestbyname(OBJ_nid2sn(i));
     if (type == NULL) {
@@ -104,8 +107,8 @@ int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a, ASN1_BIT_STRING *signature,
     p = buf_in;
 
     i2d(data, &p);
-    ret = EVP_VerifyInit_ex(&ctx, type, NULL)
-        && EVP_VerifyUpdate(&ctx, (unsigned char *)buf_in, inl);
+    ret = EVP_VerifyInit_ex(ctx, type, NULL)
+        && EVP_VerifyUpdate(ctx, (unsigned char *)buf_in, inl);
 
     OPENSSL_clear_free(buf_in, (unsigned int)inl);
 
@@ -115,7 +118,7 @@ int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a, ASN1_BIT_STRING *signature,
     }
     ret = -1;
 
-    if (EVP_VerifyFinal(&ctx, (unsigned char *)signature->data,
+    if (EVP_VerifyFinal(ctx, (unsigned char *)signature->data,
                         (unsigned int)signature->length, pkey) <= 0) {
         ASN1err(ASN1_F_ASN1_VERIFY, ERR_R_EVP_LIB);
         ret = 0;
@@ -123,7 +126,7 @@ int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a, ASN1_BIT_STRING *signature,
     }
     ret = 1;
  err:
-    EVP_MD_CTX_cleanup(&ctx);
+    EVP_MD_CTX_free(ctx);
     return (ret);
 }
 
@@ -132,7 +135,7 @@ int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a, ASN1_BIT_STRING *signature,
 int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a,
                      ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey)
 {
-    EVP_MD_CTX ctx;
+    EVP_MD_CTX *ctx = NULL;
     unsigned char *buf_in = NULL;
     int ret = -1, inl;
 
@@ -148,7 +151,11 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a,
         return -1;
     }
 
-    EVP_MD_CTX_init(&ctx);
+    ctx = EVP_MD_CTX_new();
+    if (ctx == NULL) {
+        ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
 
     /* Convert signature OID into digest and public key OIDs */
     if (!OBJ_find_sigid_algs(OBJ_obj2nid(a->algorithm), &mdnid, &pknid)) {
@@ -161,7 +168,7 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a,
                     ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
             goto err;
         }
-        ret = pkey->ameth->item_verify(&ctx, it, asn, a, signature, pkey);
+        ret = pkey->ameth->item_verify(ctx, it, asn, a, signature, pkey);
         /*
          * Return value of 2 means carry on, anything else means we exit
          * straight away: either a fatal error of the underlying verification
@@ -185,7 +192,7 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a,
             goto err;
         }
 
-        if (!EVP_DigestVerifyInit(&ctx, NULL, type, NULL, pkey)) {
+        if (!EVP_DigestVerifyInit(ctx, NULL, type, NULL, pkey)) {
             ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB);
             ret = 0;
             goto err;
@@ -200,7 +207,7 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a,
         goto err;
     }
 
-    ret = EVP_DigestVerifyUpdate(&ctx, buf_in, inl);
+    ret = EVP_DigestVerifyUpdate(ctx, buf_in, inl);
 
     OPENSSL_clear_free(buf_in, (unsigned int)inl);
 
@@ -210,7 +217,7 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a,
     }
     ret = -1;
 
-    if (EVP_DigestVerifyFinal(&ctx, signature->data,
+    if (EVP_DigestVerifyFinal(ctx, signature->data,
                               (size_t)signature->length) <= 0) {
         ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB);
         ret = 0;
@@ -218,6 +225,6 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a,
     }
     ret = 1;
  err:
-    EVP_MD_CTX_cleanup(&ctx);
+    EVP_MD_CTX_free(ctx);
     return (ret);
 }
diff --git a/crypto/asn1/asn_mime.c b/crypto/asn1/asn_mime.c
index 12f6fd6..5369099 100644
--- a/crypto/asn1/asn_mime.c
+++ b/crypto/asn1/asn_mime.c
@@ -60,6 +60,7 @@
 #include <openssl/x509.h>
 #include <openssl/asn1.h>
 #include <openssl/asn1t.h>
+#include "internal/evp_int.h"
 #include "asn1_locl.h"
 
 /*
diff --git a/crypto/asn1/x_algor.c b/crypto/asn1/x_algor.c
index ca27491..5ad63eb 100644
--- a/crypto/asn1/x_algor.c
+++ b/crypto/asn1/x_algor.c
@@ -61,6 +61,7 @@
 #include <openssl/x509.h>
 #include <openssl/asn1.h>
 #include <openssl/asn1t.h>
+#include "internal/evp_int.h"
 
 ASN1_SEQUENCE(X509_ALGOR) = {
         ASN1_SIMPLE(X509_ALGOR, algorithm, ASN1_OBJECT),
diff --git a/crypto/cmac/cm_pmeth.c b/crypto/cmac/cm_pmeth.c
index 080db63..4e060f3 100644
--- a/crypto/cmac/cm_pmeth.c
+++ b/crypto/cmac/cm_pmeth.c
@@ -101,7 +101,7 @@ static int pkey_cmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
 
 static int int_update(EVP_MD_CTX *ctx, const void *data, size_t count)
 {
-    if (!CMAC_Update(ctx->pctx->data, data, count))
+    if (!CMAC_Update(EVP_MD_CTX_pkey_ctx(ctx)->data, data, count))
         return 0;
     return 1;
 }
@@ -109,7 +109,7 @@ static int int_update(EVP_MD_CTX *ctx, const void *data, size_t count)
 static int cmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
 {
     EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT);
-    mctx->update = int_update;
+    EVP_MD_CTX_set_update_fn(mctx, int_update);
     return 1;
 }
 
diff --git a/crypto/cms/cms_asn1.c b/crypto/cms/cms_asn1.c
index e044cf5..3b9f7b5 100644
--- a/crypto/cms/cms_asn1.c
+++ b/crypto/cms/cms_asn1.c
@@ -95,8 +95,7 @@ static int cms_si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
         CMS_SignerInfo *si = (CMS_SignerInfo *)*pval;
         EVP_PKEY_free(si->pkey);
         X509_free(si->signer);
-        if (si->pctx)
-            EVP_MD_CTX_cleanup(&si->mctx);
+        EVP_MD_CTX_free(si->mctx);
     }
     return 1;
 }
diff --git a/crypto/cms/cms_dd.c b/crypto/cms/cms_dd.c
index 426f8cd..9ac45b5 100644
--- a/crypto/cms/cms_dd.c
+++ b/crypto/cms/cms_dd.c
@@ -99,19 +99,23 @@ BIO *cms_DigestedData_init_bio(CMS_ContentInfo *cms)
 
 int cms_DigestedData_do_final(CMS_ContentInfo *cms, BIO *chain, int verify)
 {
-    EVP_MD_CTX mctx;
+    EVP_MD_CTX *mctx = EVP_MD_CTX_new();
     unsigned char md[EVP_MAX_MD_SIZE];
     unsigned int mdlen;
     int r = 0;
     CMS_DigestedData *dd;
-    EVP_MD_CTX_init(&mctx);
+
+    if (mctx == NULL) {
+        CMSerr(CMS_F_CMS_DIGESTEDDATA_DO_FINAL, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
 
     dd = cms->d.digestedData;
 
-    if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, dd->digestAlgorithm))
+    if (!cms_DigestAlgorithm_find_ctx(mctx, chain, dd->digestAlgorithm))
         goto err;
 
-    if (EVP_DigestFinal_ex(&mctx, md, &mdlen) <= 0)
+    if (EVP_DigestFinal_ex(mctx, md, &mdlen) <= 0)
         goto err;
 
     if (verify) {
@@ -133,7 +137,7 @@ int cms_DigestedData_do_final(CMS_ContentInfo *cms, BIO *chain, int verify)
     }
 
  err:
-    EVP_MD_CTX_cleanup(&mctx);
+    EVP_MD_CTX_free(mctx);
 
     return r;
 
diff --git a/crypto/cms/cms_lcl.h b/crypto/cms/cms_lcl.h
index 227356b..3d41d4f 100644
--- a/crypto/cms/cms_lcl.h
+++ b/crypto/cms/cms_lcl.h
@@ -137,7 +137,7 @@ struct CMS_SignerInfo_st {
     X509 *signer;
     EVP_PKEY *pkey;
     /* Digest and public key context for alternative parameters */
-    EVP_MD_CTX mctx;
+    EVP_MD_CTX *mctx;
     EVP_PKEY_CTX *pctx;
 };
 
diff --git a/crypto/cms/cms_sd.c b/crypto/cms/cms_sd.c
index 1720bcd..5c39746 100644
--- a/crypto/cms/cms_sd.c
+++ b/crypto/cms/cms_sd.c
@@ -287,9 +287,14 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
 
     si->pkey = pk;
     si->signer = signer;
-    EVP_MD_CTX_init(&si->mctx);
+    si->mctx = EVP_MD_CTX_new();
     si->pctx = NULL;
 
+    if (si->mctx == NULL) {
+        CMSerr(CMS_F_CMS_ADD1_SIGNER, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
     if (flags & CMS_USE_KEYID) {
         si->version = 3;
         if (sd->version < 3)
@@ -387,7 +392,7 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
                 goto err;
             if (EVP_PKEY_CTX_set_signature_md(si->pctx, md) <= 0)
                 goto err;
-        } else if (EVP_DigestSignInit(&si->mctx, &si->pctx, md, NULL, pk) <=
+        } else if (EVP_DigestSignInit(si->mctx, &si->pctx, md, NULL, pk) <=
                    0)
             goto err;
     }
@@ -444,7 +449,7 @@ EVP_PKEY_CTX *CMS_SignerInfo_get0_pkey_ctx(CMS_SignerInfo *si)
 
 EVP_MD_CTX *CMS_SignerInfo_get0_md_ctx(CMS_SignerInfo *si)
 {
-    return &si->mctx;
+    return si->mctx;
 }
 
 STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms)
@@ -571,17 +576,21 @@ ASN1_OCTET_STRING *CMS_SignerInfo_get0_signature(CMS_SignerInfo *si)
 static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
                                        CMS_SignerInfo *si, BIO *chain)
 {
-    EVP_MD_CTX mctx;
+    EVP_MD_CTX *mctx = EVP_MD_CTX_new();
     int r = 0;
     EVP_PKEY_CTX *pctx = NULL;
-    EVP_MD_CTX_init(&mctx);
+
+    if (mctx == NULL) {
+        CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
 
     if (!si->pkey) {
         CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, CMS_R_NO_PRIVATE_KEY);
         return 0;
     }
 
-    if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, si->digestAlgorithm))
+    if (!cms_DigestAlgorithm_find_ctx(mctx, chain, si->digestAlgorithm))
         goto err;
     /* Set SignerInfo algortihm details if we used custom parametsr */
     if (si->pctx && !cms_sd_asn1_ctrl(si, 0))
@@ -596,7 +605,7 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
             cms->d.signedData->encapContentInfo->eContentType;
         unsigned char md[EVP_MAX_MD_SIZE];
         unsigned int mdlen;
-        if (!EVP_DigestFinal_ex(&mctx, md, &mdlen))
+        if (!EVP_DigestFinal_ex(mctx, md, &mdlen))
             goto err;
         if (!CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest,
                                          V_ASN1_OCTET_STRING, md, mdlen))
@@ -613,7 +622,7 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
         unsigned char md[EVP_MAX_MD_SIZE];
         unsigned int mdlen;
         pctx = si->pctx;
-        if (!EVP_DigestFinal_ex(&mctx, md, &mdlen))
+        if (!EVP_DigestFinal_ex(mctx, md, &mdlen))
             goto err;
         siglen = EVP_PKEY_size(si->pkey);
         sig = OPENSSL_malloc(siglen);
@@ -634,7 +643,7 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
             CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, ERR_R_MALLOC_FAILURE);
             goto err;
         }
-        if (!EVP_SignFinal(&mctx, sig, &siglen, si->pkey)) {
+        if (!EVP_SignFinal(mctx, sig, &siglen, si->pkey)) {
             CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, CMS_R_SIGNFINAL_ERROR);
             OPENSSL_free(sig);
             goto err;
@@ -645,7 +654,7 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
     r = 1;
 
  err:
-    EVP_MD_CTX_cleanup(&mctx);
+    EVP_MD_CTX_free(mctx);
     EVP_PKEY_CTX_free(pctx);
     return r;
 
@@ -668,7 +677,7 @@ int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain)
 
 int CMS_SignerInfo_sign(CMS_SignerInfo *si)
 {
-    EVP_MD_CTX *mctx = &si->mctx;
+    EVP_MD_CTX *mctx = si->mctx;
     EVP_PKEY_CTX *pctx;
     unsigned char *abuf = NULL;
     int alen;
@@ -687,7 +696,7 @@ int CMS_SignerInfo_sign(CMS_SignerInfo *si)
     if (si->pctx)
         pctx = si->pctx;
     else {
-        EVP_MD_CTX_init(mctx);
+        EVP_MD_CTX_reset(mctx);
         if (EVP_DigestSignInit(mctx, &pctx, md, NULL, si->pkey) <= 0)
             goto err;
     }
@@ -719,7 +728,7 @@ int CMS_SignerInfo_sign(CMS_SignerInfo *si)
         goto err;
     }
 
-    EVP_MD_CTX_cleanup(mctx);
+    EVP_MD_CTX_reset(mctx);
 
     ASN1_STRING_set0(si->signature, abuf, siglen);
 
@@ -727,14 +736,14 @@ int CMS_SignerInfo_sign(CMS_SignerInfo *si)
 
  err:
     OPENSSL_free(abuf);
-    EVP_MD_CTX_cleanup(mctx);
+    EVP_MD_CTX_reset(mctx);
     return 0;
 
 }
 
 int CMS_SignerInfo_verify(CMS_SignerInfo *si)
 {
-    EVP_MD_CTX *mctx = &si->mctx;
+    EVP_MD_CTX *mctx = NULL;
     unsigned char *abuf = NULL;
     int alen, r = -1;
     const EVP_MD *md = NULL;
@@ -747,7 +756,9 @@ int CMS_SignerInfo_verify(CMS_SignerInfo *si)
     md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
     if (md == NULL)
         return -1;
-    EVP_MD_CTX_init(mctx);
+    if (si->mctx == NULL)
+        si->mctx = EVP_MD_CTX_new();
+    mctx = si->mctx;
     if (EVP_DigestVerifyInit(mctx, &si->pctx, md, NULL, si->pkey) <= 0)
         goto err;
 
@@ -769,7 +780,7 @@ int CMS_SignerInfo_verify(CMS_SignerInfo *si)
     if (r <= 0)
         CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_VERIFICATION_FAILURE);
  err:
-    EVP_MD_CTX_cleanup(mctx);
+    EVP_MD_CTX_reset(mctx);
     return r;
 }
 
@@ -806,12 +817,16 @@ BIO *cms_SignedData_init_bio(CMS_ContentInfo *cms)
 int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain)
 {
     ASN1_OCTET_STRING *os = NULL;
-    EVP_MD_CTX mctx;
+    EVP_MD_CTX *mctx = EVP_MD_CTX_new();
     EVP_PKEY_CTX *pkctx = NULL;
     int r = -1;
     unsigned char mval[EVP_MAX_MD_SIZE];
     unsigned int mlen;
-    EVP_MD_CTX_init(&mctx);
+
+    if (mctx == NULL) {
+        CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
     /* If we have any signed attributes look for messageDigest value */
     if (CMS_signed_get_attr_count(si) >= 0) {
         os = CMS_signed_get0_data_by_OBJ(si,
@@ -824,10 +839,10 @@ int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain)
         }
     }
 
-    if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, si->digestAlgorithm))
+    if (!cms_DigestAlgorithm_find_ctx(mctx, chain, si->digestAlgorithm))
         goto err;
 
-    if (EVP_DigestFinal_ex(&mctx, mval, &mlen) <= 0) {
+    if (EVP_DigestFinal_ex(mctx, mval, &mlen) <= 0) {
         CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
                CMS_R_UNABLE_TO_FINALIZE_CONTEXT);
         goto err;
@@ -849,7 +864,7 @@ int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain)
         } else
             r = 1;
     } else {
-        const EVP_MD *md = EVP_MD_CTX_md(&mctx);
+        const EVP_MD *md = EVP_MD_CTX_md(mctx);
         pkctx = EVP_PKEY_CTX_new(si->pkey, NULL);
         if (pkctx == NULL)
             goto err;
@@ -871,7 +886,7 @@ int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain)
 
  err:
     EVP_PKEY_CTX_free(pkctx);
-    EVP_MD_CTX_cleanup(&mctx);
+    EVP_MD_CTX_free(mctx);
     return r;
 
 }
diff --git a/crypto/dh/dh_kdf.c b/crypto/dh/dh_kdf.c
index 5597960..8ce8498 100644
--- a/crypto/dh/dh_kdf.c
+++ b/crypto/dh/dh_kdf.c
@@ -144,7 +144,7 @@ int DH_KDF_X9_42(unsigned char *out, size_t outlen,
                  ASN1_OBJECT *key_oid,
                  const unsigned char *ukm, size_t ukmlen, const EVP_MD *md)
 {
-    EVP_MD_CTX mctx;
+    EVP_MD_CTX *mctx = NULL;
     int rv = 0;
     unsigned int i;
     size_t mdlen;
@@ -152,31 +152,33 @@ int DH_KDF_X9_42(unsigned char *out, size_t outlen,
     int derlen;
     if (Zlen > DH_KDF_MAX)
         return 0;
+    mctx = EVP_MD_CTX_new();
+    if (mctx == NULL)
+        return 0;
     mdlen = EVP_MD_size(md);
-    EVP_MD_CTX_init(&mctx);
     derlen = dh_sharedinfo_encode(&der, &ctr, key_oid, outlen, ukm, ukmlen);
     if (derlen == 0)
         goto err;
     for (i = 1;; i++) {
         unsigned char mtmp[EVP_MAX_MD_SIZE];
-        EVP_DigestInit_ex(&mctx, md, NULL);
-        if (!EVP_DigestUpdate(&mctx, Z, Zlen))
+        EVP_DigestInit_ex(mctx, md, NULL);
+        if (!EVP_DigestUpdate(mctx, Z, Zlen))
             goto err;
         ctr[3] = i & 0xFF;
         ctr[2] = (i >> 8) & 0xFF;
         ctr[1] = (i >> 16) & 0xFF;
         ctr[0] = (i >> 24) & 0xFF;
-        if (!EVP_DigestUpdate(&mctx, der, derlen))
+        if (!EVP_DigestUpdate(mctx, der, derlen))
             goto err;
         if (outlen >= mdlen) {
-            if (!EVP_DigestFinal(&mctx, out, NULL))
+            if (!EVP_DigestFinal(mctx, out, NULL))
                 goto err;
             outlen -= mdlen;
             if (outlen == 0)
                 break;
             out += mdlen;
         } else {
-            if (!EVP_DigestFinal(&mctx, mtmp, NULL))
+            if (!EVP_DigestFinal(mctx, mtmp, NULL))
                 goto err;
             memcpy(out, mtmp, outlen);
             OPENSSL_cleanse(mtmp, mdlen);
@@ -186,7 +188,7 @@ int DH_KDF_X9_42(unsigned char *out, size_t outlen,
     rv = 1;
  err:
     OPENSSL_free(der);
-    EVP_MD_CTX_cleanup(&mctx);
+    EVP_MD_CTX_free(mctx);
     return rv;
 }
 #endif
diff --git a/crypto/dsa/dsa_gen.c b/crypto/dsa/dsa_gen.c
index 106ec3c..d6e3614 100644
--- a/crypto/dsa/dsa_gen.c
+++ b/crypto/dsa/dsa_gen.c
@@ -360,10 +360,11 @@ int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
     int counter = 0;
     int r = 0;
     BN_CTX *ctx = NULL;
-    EVP_MD_CTX mctx;
+    EVP_MD_CTX *mctx = EVP_MD_CTX_new();
     unsigned int h = 2;
 
-    EVP_MD_CTX_init(&mctx);
+    if (mctx == NULL)
+        goto err;
 
     if (evpmd == NULL) {
         if (N == 160)
@@ -374,7 +375,7 @@ int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
             evpmd = EVP_sha256();
     }
 
-    mdsize = M_EVP_MD_size(evpmd);
+    mdsize = EVP_MD_size(evpmd);
     /* If unverificable g generation only don't need seed */
     if (!ret->p || !ret->q || idx >= 0) {
         if (seed_len == 0)
@@ -582,15 +583,15 @@ int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
             md[0] = idx & 0xff;
             md[1] = (h >> 8) & 0xff;
             md[2] = h & 0xff;
-            if (!EVP_DigestInit_ex(&mctx, evpmd, NULL))
+            if (!EVP_DigestInit_ex(mctx, evpmd, NULL))
                 goto err;
-            if (!EVP_DigestUpdate(&mctx, seed_tmp, seed_len))
+            if (!EVP_DigestUpdate(mctx, seed_tmp, seed_len))
                 goto err;
-            if (!EVP_DigestUpdate(&mctx, ggen, sizeof(ggen)))
+            if (!EVP_DigestUpdate(mctx, ggen, sizeof(ggen)))
                 goto err;
-            if (!EVP_DigestUpdate(&mctx, md, 3))
+            if (!EVP_DigestUpdate(mctx, md, 3))
                 goto err;
-            if (!EVP_DigestFinal_ex(&mctx, md, NULL))
+            if (!EVP_DigestFinal_ex(mctx, md, NULL))
                 goto err;
             if (!BN_bin2bn(md, mdsize, test))
                 goto err;
@@ -639,7 +640,7 @@ int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
         BN_CTX_end(ctx);
     BN_CTX_free(ctx);
     BN_MONT_CTX_free(mont);
-    EVP_MD_CTX_cleanup(&mctx);
+    EVP_MD_CTX_free(mctx);
     return ok;
 }
 
diff --git a/crypto/ecdh/ech_kdf.c b/crypto/ecdh/ech_kdf.c
index 1e77c6f..cbcbfd9 100644
--- a/crypto/ecdh/ech_kdf.c
+++ b/crypto/ecdh/ech_kdf.c
@@ -64,7 +64,7 @@ int ECDH_KDF_X9_62(unsigned char *out, size_t outlen,
                    const unsigned char *sinfo, size_t sinfolen,
                    const EVP_MD *md)
 {
-    EVP_MD_CTX mctx;
+    EVP_MD_CTX *mctx = NULL;
     int rv = 0;
     unsigned int i;
     size_t mdlen;
@@ -72,30 +72,32 @@ int ECDH_KDF_X9_62(unsigned char *out, size_t outlen,
     if (sinfolen > ECDH_KDF_MAX || outlen > ECDH_KDF_MAX
         || Zlen > ECDH_KDF_MAX)
         return 0;
+    mctx = EVP_MD_CTX_new();
+    if (mctx == NULL)
+        return 0;
     mdlen = EVP_MD_size(md);
-    EVP_MD_CTX_init(&mctx);
     for (i = 1;; i++) {
         unsigned char mtmp[EVP_MAX_MD_SIZE];
-        EVP_DigestInit_ex(&mctx, md, NULL);
+        EVP_DigestInit_ex(mctx, md, NULL);
         ctr[3] = i & 0xFF;
         ctr[2] = (i >> 8) & 0xFF;
         ctr[1] = (i >> 16) & 0xFF;
         ctr[0] = (i >> 24) & 0xFF;
-        if (!EVP_DigestUpdate(&mctx, Z, Zlen))
+        if (!EVP_DigestUpdate(mctx, Z, Zlen))
             goto err;
-        if (!EVP_DigestUpdate(&mctx, ctr, sizeof(ctr)))
+        if (!EVP_DigestUpdate(mctx, ctr, sizeof(ctr)))
             goto err;
-        if (!EVP_DigestUpdate(&mctx, sinfo, sinfolen))
+        if (!EVP_DigestUpdate(mctx, sinfo, sinfolen))
             goto err;
         if (outlen >= mdlen) {
-            if (!EVP_DigestFinal(&mctx, out, NULL))
+            if (!EVP_DigestFinal(mctx, out, NULL))
                 goto err;
             outlen -= mdlen;
             if (outlen == 0)
                 break;
             out += mdlen;
         } else {
-            if (!EVP_DigestFinal(&mctx, mtmp, NULL))
+            if (!EVP_DigestFinal(mctx, mtmp, NULL))
                 goto err;
             memcpy(out, mtmp, outlen);
             OPENSSL_cleanse(mtmp, mdlen);
@@ -104,6 +106,6 @@ int ECDH_KDF_X9_62(unsigned char *out, size_t outlen,
     }
     rv = 1;
  err:
-    EVP_MD_CTX_cleanup(&mctx);
+    EVP_MD_CTX_free(mctx);
     return rv;
 }
diff --git a/crypto/engine/eng_openssl.c b/crypto/engine/eng_openssl.c
index ba9adf0..b81f9c6 100644
--- a/crypto/engine/eng_openssl.c
+++ b/crypto/engine/eng_openssl.c
@@ -111,6 +111,8 @@
 # undef TEST_ENG_OPENSSL_RC4_P_CIPHER
 #endif
 
+static int openssl_destroy(ENGINE *e);
+
 #ifdef TEST_ENG_OPENSSL_RC4
 static int openssl_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
                            const int **nids, int nid);
@@ -144,6 +146,7 @@ static int bind_helper(ENGINE *e)
 {
     if (!ENGINE_set_id(e, engine_openssl_id)
         || !ENGINE_set_name(e, engine_openssl_name)
+        || !ENGINE_set_destroy_function(e, openssl_destroy)
 #ifndef TEST_ENG_OPENSSL_NO_ALGORITHMS
 # ifndef OPENSSL_NO_RSA
         || !ENGINE_set_RSA(e, RSA_get_default_method())
@@ -326,15 +329,13 @@ static int openssl_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
 #ifdef TEST_ENG_OPENSSL_SHA
 /* Much the same sort of comment as for TEST_ENG_OPENSSL_RC4 */
 # include <openssl/sha.h>
-static const int test_digest_nids[] = { NID_sha1 };
 
-static const int test_digest_nids_number = 1;
 static int test_sha1_init(EVP_MD_CTX *ctx)
 {
 # ifdef TEST_ENG_OPENSSL_SHA_P_INIT
     fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_init() called\n");
 # endif
-    return SHA1_Init(ctx->md_data);
+    return SHA1_Init(EVP_MD_CTX_md_data(ctx));
 }
 
 static int test_sha1_update(EVP_MD_CTX *ctx, const void *data, size_t count)
@@ -342,7 +343,7 @@ static int test_sha1_update(EVP_MD_CTX *ctx, const void *data, size_t count)
 # ifdef TEST_ENG_OPENSSL_SHA_P_UPDATE
     fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_update() called\n");
 # endif
-    return SHA1_Update(ctx->md_data, data, count);
+    return SHA1_Update(EVP_MD_CTX_md_data(ctx), data, count);
 }
 
 static int test_sha1_final(EVP_MD_CTX *ctx, unsigned char *md)
@@ -350,34 +351,63 @@ static int test_sha1_final(EVP_MD_CTX *ctx, unsigned char *md)
 # ifdef TEST_ENG_OPENSSL_SHA_P_FINAL
     fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_final() called\n");
 # endif
-    return SHA1_Final(md, ctx->md_data);
+    return SHA1_Final(md, EVP_MD_CTX_md_data(ctx));
 }
 
-static const EVP_MD test_sha_md = {
-    NID_sha1,
-    NID_sha1WithRSAEncryption,
-    SHA_DIGEST_LENGTH,
-    0,
-    test_sha1_init,
-    test_sha1_update,
-    test_sha1_final,
-    NULL,
-    NULL,
-    SHA_CBLOCK,
-    sizeof(EVP_MD *) + sizeof(SHA_CTX),
-};
+static EVP_MD *sha1_md = NULL;
+static const EVP_MD *test_sha_md(void)
+{
+    if (sha1_md == NULL) {
+        EVP_MD *md;
+
+        if ((md = EVP_MD_meth_new(NID_sha1, NID_sha1WithRSAEncryption)) == NULL
+            || !EVP_MD_meth_set_result_size(md, SHA_DIGEST_LENGTH)
+            || !EVP_MD_meth_set_input_blocksize(md, SHA_CBLOCK)
+            || !EVP_MD_meth_set_app_datasize(md,
+                                             sizeof(EVP_MD *) + sizeof(SHA_CTX))
+            || !EVP_MD_meth_set_flags(md, 0)
+            || !EVP_MD_meth_set_init(md, test_sha1_init)
+            || !EVP_MD_meth_set_update(md, test_sha1_update)
+            || !EVP_MD_meth_set_final(md, test_sha1_final)) {
+            EVP_MD_meth_free(md);
+            md = NULL;
+        }
+        sha1_md = md;
+    }
+    return sha1_md;
+}
+static void test_sha_md_destroy(void)
+{
+    EVP_MD_meth_free(sha1_md);
+    sha1_md = NULL;
+}
+static int test_digest_nids(const int **nids)
+{
+    static int digest_nids[2] = { 0, 0 };
+    static int pos = 0;
+    static int init = 0;
+
+    if (!init) {
+        const EVP_MD *md;
+        if ((md = test_sha_md()) != NULL)
+            digest_nids[pos++] = EVP_MD_type(md);
+        digest_nids[pos] = 0;
+        init = 1;
+    }
+    *nids = digest_nids;
+    return pos;
+}
 
 static int openssl_digests(ENGINE *e, const EVP_MD **digest,
                            const int **nids, int nid)
 {
     if (!digest) {
         /* We are returning a list of supported nids */
-        *nids = test_digest_nids;
-        return test_digest_nids_number;
+        return test_digest_nids(nids);
     }
     /* We are being asked for a specific digest */
     if (nid == NID_sha1)
-        *digest = &test_sha_md;
+        *digest = test_sha_md();
     else {
 # ifdef TEST_ENG_OPENSSL_SHA_OTHERS
         fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) returning NULL for "
@@ -420,7 +450,7 @@ static EVP_PKEY *openssl_load_privkey(ENGINE *eng, const char *key_id,
 typedef struct {
     const EVP_MD *md;           /* MD for HMAC use */
     ASN1_OCTET_STRING ktmp;     /* Temp storage for key */
-    HMAC_CTX ctx;
+    HMAC_CTX *ctx;
 } OSSL_HMAC_PKEY_CTX;
 
 static int ossl_hmac_init(EVP_PKEY_CTX *ctx)
@@ -431,7 +461,7 @@ static int ossl_hmac_init(EVP_PKEY_CTX *ctx)
     if (hctx == NULL)
         return 0;
     hctx->ktmp.type = V_ASN1_OCTET_STRING;
-    HMAC_CTX_init(&hctx->ctx);
+    hctx->ctx = HMAC_CTX_new();
     EVP_PKEY_CTX_set_data(ctx, hctx);
     EVP_PKEY_CTX_set0_keygen_info(ctx, NULL, 0);
 # ifdef TEST_ENG_OPENSSL_HMAC_INIT
@@ -448,8 +478,7 @@ static int ossl_hmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
     sctx = EVP_PKEY_CTX_get_data(src);
     dctx = EVP_PKEY_CTX_get_data(dst);
     dctx->md = sctx->md;
-    HMAC_CTX_init(&dctx->ctx);
-    if (!HMAC_CTX_copy(&dctx->ctx, &sctx->ctx))
+    if (!HMAC_CTX_copy(dctx->ctx, sctx->ctx))
         return 0;
     if (sctx->ktmp.data) {
         if (!ASN1_OCTET_STRING_set(&dctx->ktmp,
@@ -463,7 +492,7 @@ static void ossl_hmac_cleanup(EVP_PKEY_CTX *ctx)
 {
     OSSL_HMAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
 
-    HMAC_CTX_cleanup(&hctx->ctx);
+    HMAC_CTX_free(hctx->ctx);
     OPENSSL_clear_free(hctx->ktmp.data, hctx->ktmp.length);
     OPENSSL_free(hctx);
 }
@@ -484,8 +513,8 @@ static int ossl_hmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
 
 static int ossl_int_update(EVP_MD_CTX *ctx, const void *data, size_t count)
 {
-    OSSL_HMAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx->pctx);
-    if (!HMAC_Update(&hctx->ctx, data, count))
+    OSSL_HMAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(EVP_MD_CTX_pkey_ctx(ctx));
+    if (!HMAC_Update(hctx->ctx, data, count))
         return 0;
     return 1;
 }
@@ -493,7 +522,7 @@ static int ossl_int_update(EVP_MD_CTX *ctx, const void *data, size_t count)
 static int ossl_hmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
 {
     EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT);
-    mctx->update = ossl_int_update;
+    EVP_MD_CTX_set_update_fn(mctx, ossl_int_update);
     return 1;
 }
 
@@ -510,7 +539,7 @@ static int ossl_hmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig,
     if (!sig)
         return 1;
 
-    if (!HMAC_Final(&hctx->ctx, sig, &hlen))
+    if (!HMAC_Final(hctx->ctx, sig, &hlen))
         return 0;
     *siglen = (size_t)hlen;
     return 1;
@@ -537,7 +566,7 @@ static int ossl_hmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
     case EVP_PKEY_CTRL_DIGESTINIT:
         pk = EVP_PKEY_CTX_get0_pkey(ctx);
         key = EVP_PKEY_get0(pk);
-        if (!HMAC_Init_ex(&hctx->ctx, key->data, key->length, hctx->md, NULL))
+        if (!HMAC_Init_ex(hctx->ctx, key->data, key->length, hctx->md, NULL))
             return 0;
         break;
 
@@ -616,3 +645,10 @@ static int ossl_pkey_meths(ENGINE *e, EVP_PKEY_METHOD **pmeth,
 }
 
 #endif
+
+int openssl_destroy(ENGINE *e)
+{
+    test_sha_md_destroy();
+    return 1;
+}
+
diff --git a/crypto/evp/Makefile b/crypto/evp/Makefile
index ee0998d..3972dc8 100644
--- a/crypto/evp/Makefile
+++ b/crypto/evp/Makefile
@@ -111,7 +111,8 @@ bio_md.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
 bio_md.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
 bio_md.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
 bio_md.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-bio_md.o: ../include/internal/cryptlib.h bio_md.c
+bio_md.o: ../include/internal/cryptlib.h ../include/internal/evp_int.h bio_md.c
+bio_md.o: evp_locl.h
 bio_ok.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 bio_ok.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 bio_ok.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
@@ -121,7 +122,7 @@ bio_ok.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
 bio_ok.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
 bio_ok.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
 bio_ok.o: ../../include/openssl/symhacks.h ../include/internal/cryptlib.h
-bio_ok.o: bio_ok.c
+bio_ok.o: ../include/internal/evp_int.h bio_ok.c
 c_all.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 c_all.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 c_all.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
@@ -173,7 +174,8 @@ digest.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
 digest.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
 digest.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
 digest.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-digest.o: ../include/internal/cryptlib.h digest.c
+digest.o: ../include/internal/cryptlib.h ../include/internal/evp_int.h digest.c
+digest.o: evp_locl.h
 e_aes.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
 e_aes.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
 e_aes.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
@@ -430,7 +432,7 @@ evp_lib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 evp_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 evp_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
 evp_lib.o: ../../include/openssl/symhacks.h ../include/internal/cryptlib.h
-evp_lib.o: evp_lib.c
+evp_lib.o: ../include/internal/evp_int.h evp_lib.c evp_locl.h
 evp_pbe.o: ../../e_os.h ../../include/openssl/asn1.h
 evp_pbe.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 evp_pbe.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
@@ -481,7 +483,7 @@ m_md4.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
 m_md4.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
 m_md4.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
 m_md4.o: ../../include/openssl/x509_vfy.h ../include/internal/cryptlib.h
-m_md4.o: m_md4.c
+m_md4.o: ../include/internal/evp_int.h m_md4.c
 m_md5.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 m_md5.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 m_md5.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
@@ -495,7 +497,7 @@ m_md5.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
 m_md5.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
 m_md5.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
 m_md5.o: ../../include/openssl/x509_vfy.h ../include/internal/cryptlib.h
-m_md5.o: m_md5.c
+m_md5.o: ../include/internal/evp_int.h m_md5.c
 m_md5_sha1.o: ../../e_os.h ../../include/openssl/asn1.h
 m_md5_sha1.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 m_md5_sha1.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
@@ -510,7 +512,8 @@ m_md5_sha1.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
 m_md5_sha1.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
 m_md5_sha1.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
 m_md5_sha1.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-m_md5_sha1.o: ../include/internal/cryptlib.h m_md5_sha1.c
+m_md5_sha1.o: ../include/internal/cryptlib.h ../include/internal/evp_int.h
+m_md5_sha1.o: m_md5_sha1.c
 m_mdc2.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 m_mdc2.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 m_mdc2.o: ../../include/openssl/des.h ../../include/openssl/e_os2.h
@@ -524,7 +527,7 @@ m_mdc2.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
 m_mdc2.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
 m_mdc2.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
 m_mdc2.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-m_mdc2.o: ../include/internal/cryptlib.h m_mdc2.c
+m_mdc2.o: ../include/internal/cryptlib.h ../include/internal/evp_int.h m_mdc2.c
 m_null.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 m_null.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 m_null.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
@@ -537,7 +540,7 @@ m_null.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 m_null.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
 m_null.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
 m_null.o: ../../include/openssl/x509_vfy.h ../include/internal/cryptlib.h
-m_null.o: m_null.c
+m_null.o: ../include/internal/evp_int.h m_null.c
 m_ripemd.o: ../../e_os.h ../../include/openssl/asn1.h
 m_ripemd.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 m_ripemd.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
@@ -552,7 +555,7 @@ m_ripemd.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
 m_ripemd.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
 m_ripemd.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
 m_ripemd.o: ../../include/openssl/x509_vfy.h ../include/internal/cryptlib.h
-m_ripemd.o: m_ripemd.c
+m_ripemd.o: ../include/internal/evp_int.h m_ripemd.c
 m_sha1.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 m_sha1.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 m_sha1.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
@@ -562,7 +565,7 @@ m_sha1.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
 m_sha1.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rsa.h
 m_sha1.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
 m_sha1.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-m_sha1.o: ../include/internal/cryptlib.h m_sha1.c
+m_sha1.o: ../include/internal/cryptlib.h ../include/internal/evp_int.h m_sha1.c
 m_sigver.o: ../../e_os.h ../../include/openssl/asn1.h
 m_sigver.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 m_sigver.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
@@ -576,7 +579,7 @@ m_sigver.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 m_sigver.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
 m_sigver.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
 m_sigver.o: ../../include/openssl/x509_vfy.h ../include/internal/cryptlib.h
-m_sigver.o: ../include/internal/evp_int.h m_sigver.c
+m_sigver.o: ../include/internal/evp_int.h evp_locl.h m_sigver.c
 m_wp.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 m_wp.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 m_wp.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
@@ -589,7 +592,7 @@ m_wp.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 m_wp.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
 m_wp.o: ../../include/openssl/symhacks.h ../../include/openssl/whrlpool.h
 m_wp.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-m_wp.o: ../include/internal/cryptlib.h m_wp.c
+m_wp.o: ../include/internal/cryptlib.h ../include/internal/evp_int.h m_wp.c
 names.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 names.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 names.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
@@ -602,7 +605,7 @@ names.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 names.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
 names.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
 names.o: ../../include/openssl/x509_vfy.h ../include/internal/cryptlib.h
-names.o: names.c
+names.o: ../include/internal/evp_int.h names.c
 p5_crpt.o: ../../e_os.h ../../include/openssl/asn1.h
 p5_crpt.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 p5_crpt.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
@@ -712,7 +715,7 @@ p_sign.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 p_sign.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
 p_sign.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
 p_sign.o: ../../include/openssl/x509_vfy.h ../include/internal/cryptlib.h
-p_sign.o: p_sign.c
+p_sign.o: ../include/internal/evp_int.h p_sign.c
 p_verify.o: ../../e_os.h ../../include/openssl/asn1.h
 p_verify.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 p_verify.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
@@ -726,7 +729,7 @@ p_verify.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 p_verify.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
 p_verify.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
 p_verify.o: ../../include/openssl/x509_vfy.h ../include/internal/cryptlib.h
-p_verify.o: p_verify.c
+p_verify.o: ../include/internal/evp_int.h p_verify.c
 pmeth_fn.o: ../../e_os.h ../../include/openssl/asn1.h
 pmeth_fn.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 pmeth_fn.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
diff --git a/crypto/evp/bio_md.c b/crypto/evp/bio_md.c
index 6afaf9a..24c7dc3 100644
--- a/crypto/evp/bio_md.c
+++ b/crypto/evp/bio_md.c
@@ -61,6 +61,8 @@
 #include "internal/cryptlib.h"
 #include <openssl/buffer.h>
 #include <openssl/evp.h>
+#include "internal/evp_int.h"
+#include "evp_locl.h"
 
 /*
  * BIO_put and BIO_get both add to the digest, BIO_gets returns the digest
@@ -98,7 +100,7 @@ static int md_new(BIO *bi)
 {
     EVP_MD_CTX *ctx;
 
-    ctx = EVP_MD_CTX_create();
+    ctx = EVP_MD_CTX_new();
     if (ctx == NULL)
         return (0);
 
@@ -112,7 +114,7 @@ static int md_free(BIO *a)
 {
     if (a == NULL)
         return (0);
-    EVP_MD_CTX_destroy(a->ptr);
+    EVP_MD_CTX_free(a->ptr);
     a->ptr = NULL;
     a->init = 0;
     a->flags = 0;
diff --git a/crypto/evp/bio_ok.c b/crypto/evp/bio_ok.c
index 8658f88..5f3f2de 100644
--- a/crypto/evp/bio_ok.c
+++ b/crypto/evp/bio_ok.c
@@ -125,6 +125,7 @@
 #include <openssl/bio.h>
 #include <openssl/evp.h>
 #include <openssl/rand.h>
+#include "internal/evp_int.h"
 
 static int ok_write(BIO *h, const char *buf, int num);
 static int ok_read(BIO *h, char *buf, int size);
@@ -149,7 +150,7 @@ typedef struct ok_struct {
     size_t buf_off_save;
     int cont;                   /* <= 0 when finished */
     int finished;
-    EVP_MD_CTX md;
+    EVP_MD_CTX *md;
     int blockout;               /* output block is ready */
     int sigio;                  /* must process signature */
     unsigned char buf[IOBS];
@@ -182,7 +183,7 @@ static int ok_new(BIO *bi)
 
     ctx->cont = 1;
     ctx->sigio = 1;
-    EVP_MD_CTX_init(&ctx->md);
+    ctx->md = EVP_MD_CTX_new();
     bi->init = 0;
     bi->ptr = (char *)ctx;
     bi->flags = 0;
@@ -193,7 +194,7 @@ static int ok_free(BIO *a)
 {
     if (a == NULL)
         return (0);
-    EVP_MD_CTX_cleanup(&((BIO_OK_CTX *)a->ptr)->md);
+    EVP_MD_CTX_free(((BIO_OK_CTX *)a->ptr)->md);
     OPENSSL_clear_free(a->ptr, sizeof(BIO_OK_CTX));
     a->ptr = NULL;
     a->init = 0;
@@ -412,14 +413,14 @@ static long ok_ctrl(BIO *b, int cmd, long num, void *ptr)
         break;
     case BIO_C_SET_MD:
         md = ptr;
-        if (!EVP_DigestInit_ex(&ctx->md, md, NULL))
+        if (!EVP_DigestInit_ex(ctx->md, md, NULL))
             return 0;
         b->init = 1;
         break;
     case BIO_C_GET_MD:
         if (b->init) {
             ppmd = ptr;
-            *ppmd = ctx->md.digest;
+            *ppmd = EVP_MD_CTX_md(ctx->md);
         } else
             ret = 0;
         break;
@@ -468,30 +469,36 @@ static int sig_out(BIO *b)
 {
     BIO_OK_CTX *ctx;
     EVP_MD_CTX *md;
+    const EVP_MD *digest;
+    int md_size;
+    void *md_data;
 
     ctx = b->ptr;
-    md = &ctx->md;
+    md = ctx->md;
+    digest = EVP_MD_CTX_md(md);
+    md_size = EVP_MD_size(digest);
+    md_data = EVP_MD_CTX_md_data(md);
 
-    if (ctx->buf_len + 2 * md->digest->md_size > OK_BLOCK_SIZE)
+    if (ctx->buf_len + 2 * md_size > OK_BLOCK_SIZE)
         return 1;
 
-    if (!EVP_DigestInit_ex(md, md->digest, NULL))
+    if (!EVP_DigestInit_ex(md, digest, NULL))
         goto berr;
     /*
      * FIXME: there's absolutely no guarantee this makes any sense at all,
      * particularly now EVP_MD_CTX has been restructured.
      */
-    if (RAND_bytes(md->md_data, md->digest->md_size) <= 0)
+    if (RAND_bytes(md_data, md_size) <= 0)
         goto berr;
-    memcpy(&(ctx->buf[ctx->buf_len]), md->md_data, md->digest->md_size);
-    longswap(&(ctx->buf[ctx->buf_len]), md->digest->md_size);
-    ctx->buf_len += md->digest->md_size;
+    memcpy(&(ctx->buf[ctx->buf_len]), md_data, md_size);
+    longswap(&(ctx->buf[ctx->buf_len]), md_size);
+    ctx->buf_len += md_size;
 
     if (!EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN)))
         goto berr;
     if (!EVP_DigestFinal_ex(md, &(ctx->buf[ctx->buf_len]), NULL))
         goto berr;
-    ctx->buf_len += md->digest->md_size;
+    ctx->buf_len += md_size;
     ctx->blockout = 1;
     ctx->sigio = 0;
     return 1;
@@ -506,25 +513,31 @@ static int sig_in(BIO *b)
     EVP_MD_CTX *md;
     unsigned char tmp[EVP_MAX_MD_SIZE];
     int ret = 0;
+    const EVP_MD *digest;
+    int md_size;
+    void *md_data;
 
     ctx = b->ptr;
-    md = &ctx->md;
+    md = ctx->md;
+    digest = EVP_MD_CTX_md(md);
+    md_size = EVP_MD_size(digest);
+    md_data = EVP_MD_CTX_md_data(md);
 
-    if ((int)(ctx->buf_len - ctx->buf_off) < 2 * md->digest->md_size)
+    if ((int)(ctx->buf_len - ctx->buf_off) < 2 * md_size)
         return 1;
 
-    if (!EVP_DigestInit_ex(md, md->digest, NULL))
+    if (!EVP_DigestInit_ex(md, digest, NULL))
         goto berr;
-    memcpy(md->md_data, &(ctx->buf[ctx->buf_off]), md->digest->md_size);
-    longswap(md->md_data, md->digest->md_size);
-    ctx->buf_off += md->digest->md_size;
+    memcpy(md_data, &(ctx->buf[ctx->buf_off]), md_size);
+    longswap(md_data, md_size);
+    ctx->buf_off += md_size;
 
     if (!EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN)))
         goto berr;
     if (!EVP_DigestFinal_ex(md, tmp, NULL))
         goto berr;
-    ret = memcmp(&(ctx->buf[ctx->buf_off]), tmp, md->digest->md_size) == 0;
-    ctx->buf_off += md->digest->md_size;
+    ret = memcmp(&(ctx->buf[ctx->buf_off]), tmp, md_size) == 0;
+    ctx->buf_off += md_size;
     if (ret == 1) {
         ctx->sigio = 0;
         if (ctx->buf_len != ctx->buf_off) {
@@ -547,9 +560,13 @@ static int block_out(BIO *b)
     BIO_OK_CTX *ctx;
     EVP_MD_CTX *md;
     unsigned long tl;
+    const EVP_MD *digest;
+    int md_size;
 
     ctx = b->ptr;
-    md = &ctx->md;
+    md = ctx->md;
+    digest = EVP_MD_CTX_md(md);
+    md_size = EVP_MD_size(digest);
 
     tl = ctx->buf_len - OK_BLOCK_BLOCK;
     ctx->buf[0] = (unsigned char)(tl >> 24);
@@ -561,7 +578,7 @@ static int block_out(BIO *b)
         goto berr;
     if (!EVP_DigestFinal_ex(md, &(ctx->buf[ctx->buf_len]), NULL))
         goto berr;
-    ctx->buf_len += md->digest->md_size;
+    ctx->buf_len += md_size;
     ctx->blockout = 1;
     return 1;
  berr:
@@ -575,9 +592,11 @@ static int block_in(BIO *b)
     EVP_MD_CTX *md;
     unsigned long tl = 0;
     unsigned char tmp[EVP_MAX_MD_SIZE];
+    int md_size;
 
     ctx = b->ptr;
-    md = &ctx->md;
+    md = ctx->md;
+    md_size = EVP_MD_size(EVP_MD_CTX_md(md));
 
     assert(sizeof(tl) >= OK_BLOCK_BLOCK); /* always true */
     tl = ctx->buf[0];
@@ -588,7 +607,7 @@ static int block_in(BIO *b)
     tl <<= 8;
     tl |= ctx->buf[3];
 
-    if (ctx->buf_len < tl + OK_BLOCK_BLOCK + md->digest->md_size)
+    if (ctx->buf_len < tl + OK_BLOCK_BLOCK + md_size)
         return 1;
 
     if (!EVP_DigestUpdate(md,
@@ -596,10 +615,9 @@ static int block_in(BIO *b)
         goto berr;
     if (!EVP_DigestFinal_ex(md, tmp, NULL))
         goto berr;
-    if (memcmp(&(ctx->buf[tl + OK_BLOCK_BLOCK]), tmp, md->digest->md_size) ==
-        0) {
+    if (memcmp(&(ctx->buf[tl + OK_BLOCK_BLOCK]), tmp, md_size) == 0) {
         /* there might be parts from next block lurking around ! */
-        ctx->buf_off_save = tl + OK_BLOCK_BLOCK + md->digest->md_size;
+        ctx->buf_off_save = tl + OK_BLOCK_BLOCK + md_size;
         ctx->buf_len_save = ctx->buf_len;
         ctx->buf_off = OK_BLOCK_BLOCK;
         ctx->buf_len = tl + OK_BLOCK_BLOCK;
diff --git a/crypto/evp/digest.c b/crypto/evp/digest.c
index 32a87f6..5da0e01 100644
--- a/crypto/evp/digest.c
+++ b/crypto/evp/digest.c
@@ -116,25 +116,54 @@
 #ifndef OPENSSL_NO_ENGINE
 # include <openssl/engine.h>
 #endif
+#include "internal/evp_int.h"
+#include "evp_locl.h"
 
-void EVP_MD_CTX_init(EVP_MD_CTX *ctx)
+/* This call frees resources associated with the context */
+int EVP_MD_CTX_reset(EVP_MD_CTX *ctx)
 {
+    if (ctx == NULL)
+        return 1;
+
+    /*
+     * Don't assume ctx->md_data was cleaned in EVP_Digest_Final, because
+     * sometimes only copies of the context are ever finalised.
+     */
+    if (ctx->digest && ctx->digest->cleanup
+        && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_CLEANED))
+        ctx->digest->cleanup(ctx);
+    if (ctx->digest && ctx->digest->ctx_size && ctx->md_data
+        && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)) {
+        OPENSSL_clear_free(ctx->md_data, ctx->digest->ctx_size);
+    }
+    EVP_PKEY_CTX_free(ctx->pctx);
+#ifndef OPENSSL_NO_ENGINE
+    if (ctx->engine)
+        /*
+         * The EVP_MD we used belongs to an ENGINE, release the functional
+         * reference we held for this reason.
+         */
+        ENGINE_finish(ctx->engine);
+#endif
     memset(ctx, 0, sizeof(*ctx));
+
+    return 1;
 }
 
-EVP_MD_CTX *EVP_MD_CTX_create(void)
+EVP_MD_CTX *EVP_MD_CTX_new(void)
 {
-    EVP_MD_CTX *ctx = OPENSSL_malloc(sizeof(*ctx));
-
-    if (ctx != NULL)
-        EVP_MD_CTX_init(ctx);
+    return OPENSSL_zalloc(sizeof(EVP_MD_CTX));
+}
 
-    return ctx;
+void EVP_MD_CTX_free(EVP_MD_CTX *ctx)
+{
+    EVP_MD_CTX_reset(ctx);
+    OPENSSL_free(ctx);
 }
 
 int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type)
 {
-    EVP_MD_CTX_init(ctx);
+    EVP_MD_CTX_reset(ctx);
     return EVP_DigestInit_ex(ctx, type, NULL);
 }
 
@@ -233,7 +262,7 @@ int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
 {
     int ret;
     ret = EVP_DigestFinal_ex(ctx, md, size);
-    EVP_MD_CTX_cleanup(ctx);
+    EVP_MD_CTX_reset(ctx);
     return ret;
 }
 
@@ -256,7 +285,7 @@ int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
 
 int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in)
 {
-    EVP_MD_CTX_init(out);
+    EVP_MD_CTX_reset(out);
     return EVP_MD_CTX_copy_ex(out, in);
 }
 
@@ -280,7 +309,7 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in)
         EVP_MD_CTX_set_flags(out, EVP_MD_CTX_FLAG_REUSE);
     } else
         tmp_buf = NULL;
-    EVP_MD_CTX_cleanup(out);
+    EVP_MD_CTX_reset(out);
     memcpy(out, in, sizeof(*out));
 
     if (in->md_data && out->digest->ctx_size) {
@@ -301,7 +330,7 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in)
     if (in->pctx) {
         out->pctx = EVP_PKEY_CTX_dup(in->pctx);
         if (!out->pctx) {
-            EVP_MD_CTX_cleanup(out);
+            EVP_MD_CTX_reset(out);
             return 0;
         }
     }
@@ -316,55 +345,20 @@ int EVP_Digest(const void *data, size_t count,
                unsigned char *md, unsigned int *size, const EVP_MD *type,
                ENGINE *impl)
 {
-    EVP_MD_CTX ctx;
+    EVP_MD_CTX *ctx = EVP_MD_CTX_new();
     int ret;
 
-    EVP_MD_CTX_init(&ctx);
-    EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_ONESHOT);
-    ret = EVP_DigestInit_ex(&ctx, type, impl)
-        && EVP_DigestUpdate(&ctx, data, count)
-        && EVP_DigestFinal_ex(&ctx, md, size);
-    EVP_MD_CTX_cleanup(&ctx);
+    if (ctx == NULL)
+        return 0;
+    EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_ONESHOT);
+    ret = EVP_DigestInit_ex(ctx, type, impl)
+        && EVP_DigestUpdate(ctx, data, count)
+        && EVP_DigestFinal_ex(ctx, md, size);
+    EVP_MD_CTX_free(ctx);
 
     return ret;
 }
 
-void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx)
-{
-    if (ctx) {
-        EVP_MD_CTX_cleanup(ctx);
-        OPENSSL_free(ctx);
-    }
-}
-
-/* This call frees resources associated with the context */
-int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
-{
-    /*
-     * Don't assume ctx->md_data was cleaned in EVP_Digest_Final, because
-     * sometimes only copies of the context are ever finalised.
-     */
-    if (ctx->digest && ctx->digest->cleanup
-        && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_CLEANED))
-        ctx->digest->cleanup(ctx);
-    if (ctx->digest && ctx->digest->ctx_size && ctx->md_data
-        && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)) {
-        OPENSSL_clear_free(ctx->md_data, ctx->digest->ctx_size);
-    }
-    EVP_PKEY_CTX_free(ctx->pctx);
-#ifndef OPENSSL_NO_ENGINE
-    if (ctx->engine)
-        /*
-         * The EVP_MD we used belongs to an ENGINE, release the functional
-         * reference we held for this reason.
-         */
-        ENGINE_finish(ctx->engine);
-#endif
-    memset(ctx, 0, sizeof(*ctx));
-
-    return 1;
-}
-
 int EVP_MD_CTX_ctrl(EVP_MD_CTX *ctx, int cmd, int p1, void *p2)
 {
     if (ctx->digest && ctx->digest->md_ctrl) {
diff --git a/crypto/evp/evp_key.c b/crypto/evp/evp_key.c
index 3e2c989..65f0381 100644
--- a/crypto/evp/evp_key.c
+++ b/crypto/evp/evp_key.c
@@ -123,7 +123,7 @@ int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md,
                    int datal, int count, unsigned char *key,
                    unsigned char *iv)
 {
-    EVP_MD_CTX c;
+    EVP_MD_CTX *c;
     unsigned char md_buf[EVP_MAX_MD_SIZE];
     int niv, nkey, addmd = 0;
     unsigned int mds = 0, i;
@@ -136,27 +136,29 @@ int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md,
     if (data == NULL)
         return (nkey);
 
-    EVP_MD_CTX_init(&c);
+    c = EVP_MD_CTX_new();
+    if (c == NULL)
+        goto err;
     for (;;) {
-        if (!EVP_DigestInit_ex(&c, md, NULL))
+        if (!EVP_DigestInit_ex(c, md, NULL))
             goto err;
         if (addmd++)
-            if (!EVP_DigestUpdate(&c, &(md_buf[0]), mds))
+            if (!EVP_DigestUpdate(c, &(md_buf[0]), mds))
                 goto err;
-        if (!EVP_DigestUpdate(&c, data, datal))
+        if (!EVP_DigestUpdate(c, data, datal))
             goto err;
         if (salt != NULL)
-            if (!EVP_DigestUpdate(&c, salt, PKCS5_SALT_LEN))
+            if (!EVP_DigestUpdate(c, salt, PKCS5_SALT_LEN))
                 goto err;
-        if (!EVP_DigestFinal_ex(&c, &(md_buf[0]), &mds))
+        if (!EVP_DigestFinal_ex(c, &(md_buf[0]), &mds))
             goto err;
 
         for (i = 1; i < (unsigned int)count; i++) {
-            if (!EVP_DigestInit_ex(&c, md, NULL))
+            if (!EVP_DigestInit_ex(c, md, NULL))
                 goto err;
-            if (!EVP_DigestUpdate(&c, &(md_buf[0]), mds))
+            if (!EVP_DigestUpdate(c, &(md_buf[0]), mds))
                 goto err;
-            if (!EVP_DigestFinal_ex(&c, &(md_buf[0]), &mds))
+            if (!EVP_DigestFinal_ex(c, &(md_buf[0]), &mds))
                 goto err;
         }
         i = 0;
@@ -189,7 +191,7 @@ int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md,
     }
     rv = type->key_len;
  err:
-    EVP_MD_CTX_cleanup(&c);
+    EVP_MD_CTX_free(c);
     OPENSSL_cleanse(md_buf, sizeof(md_buf));
     return rv;
 }
diff --git a/crypto/evp/evp_lib.c b/crypto/evp/evp_lib.c
index 319eede..4f55a1b 100644
--- a/crypto/evp/evp_lib.c
+++ b/crypto/evp/evp_lib.c
@@ -60,6 +60,8 @@
 #include "internal/cryptlib.h"
 #include <openssl/evp.h>
 #include <openssl/objects.h>
+#include "internal/evp_int.h"
+#include "evp_locl.h"
 
 int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
 {
@@ -309,6 +311,128 @@ unsigned long EVP_MD_flags(const EVP_MD *md)
     return md->flags;
 }
 
+EVP_MD *EVP_MD_meth_new(int md_type, int pkey_type)
+{
+    EVP_MD *md = (EVP_MD *)OPENSSL_zalloc(sizeof(EVP_MD));
+    if (md != NULL) {
+        md->type = md_type;
+        md->pkey_type = pkey_type;
+    }
+    return md;
+}
+EVP_MD *EVP_MD_meth_dup(const EVP_MD *md)
+{
+    EVP_MD *to = EVP_MD_meth_new(md->type, md->pkey_type);
+    if (md != NULL)
+        memcpy(to, md, sizeof(*to));
+    return to;
+}
+void EVP_MD_meth_free(EVP_MD *md)
+{
+    OPENSSL_free(md);
+}
+int EVP_MD_meth_set_input_blocksize(EVP_MD *md, int blocksize)
+{
+    md->block_size = blocksize;
+    return 1;
+}
+int EVP_MD_meth_set_result_size(EVP_MD *md, int resultsize)
+{
+    md->md_size = resultsize;
+    return 1;
+}
+int EVP_MD_meth_set_app_datasize(EVP_MD *md, int datasize)
+{
+    md->ctx_size = datasize;
+    return 1;
+}
+int EVP_MD_meth_set_flags(EVP_MD *md, unsigned long flags)
+{
+    md->flags = flags;
+    return 1;
+}
+int EVP_MD_meth_set_init(EVP_MD *md, int (*init)(EVP_MD_CTX *ctx))
+{
+    md->init = init;
+    return 1;
+}
+int EVP_MD_meth_set_update(EVP_MD *md, int (*update)(EVP_MD_CTX *ctx,
+                                                     const void *data,
+                                                     size_t count))
+{
+    md->update = update;
+    return 1;
+}
+int EVP_MD_meth_set_final(EVP_MD *md, int (*final)(EVP_MD_CTX *ctx,
+                                                   unsigned char *md))
+{
+    md->final = final;
+    return 1;
+}
+int EVP_MD_meth_set_copy(EVP_MD *md, int (*copy)(EVP_MD_CTX *to,
+                                                 const EVP_MD_CTX *from))
+{
+    md->copy = copy;
+    return 1;
+}
+int EVP_MD_meth_set_cleanup(EVP_MD *md, int (*cleanup)(EVP_MD_CTX *ctx))
+{
+    md->cleanup = cleanup;
+    return 1;
+}
+int EVP_MD_meth_set_ctrl(EVP_MD *md, int (*ctrl)(EVP_MD_CTX *ctx, int cmd,
+                                                 int p1, void *p2))
+{
+    md->md_ctrl = ctrl;
+    return 1;
+}
+
+int EVP_MD_meth_get_input_blocksize(const EVP_MD *md)
+{
+    return md->block_size;
+}
+int EVP_MD_meth_get_result_size(const EVP_MD *md)
+{
+    return md->md_size;
+}
+int EVP_MD_meth_get_app_datasize(const EVP_MD *md)
+{
+    return md->ctx_size;
+}
+unsigned long EVP_MD_meth_get_flags(const EVP_MD *md)
+{
+    return md->block_size;
+}
+int (*EVP_MD_meth_get_init(const EVP_MD *md))(EVP_MD_CTX *ctx)
+{
+    return md->init;
+}
+int (*EVP_MD_meth_get_update(const EVP_MD *md))(EVP_MD_CTX *ctx,
+                                                const void *data,
+                                                size_t count)
+{
+    return md->update;
+}
+int (*EVP_MD_meth_get_final(const EVP_MD *md))(EVP_MD_CTX *ctx,
+                                               unsigned char *md)
+{
+    return md->final;
+}
+int (*EVP_MD_meth_get_copy(const EVP_MD *md))(EVP_MD_CTX *to,
+                                              const EVP_MD_CTX *from)
+{
+    return md->copy;
+}
+int (*EVP_MD_meth_get_cleanup(const EVP_MD *md))(EVP_MD_CTX *ctx)
+{
+    return md->cleanup;
+}
+int (*EVP_MD_meth_get_ctrl(const EVP_MD *md))(EVP_MD_CTX *ctx, int cmd,
+                                              int p1, void *p2)
+{
+    return md->md_ctrl;
+}
+
 const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx)
 {
     if (!ctx)
@@ -316,6 +440,29 @@ const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx)
     return ctx->digest;
 }
 
+EVP_PKEY_CTX *EVP_MD_CTX_pkey_ctx(const EVP_MD_CTX *ctx)
+{
+    return ctx->pctx;
+}
+
+void *EVP_MD_CTX_md_data(const EVP_MD_CTX *ctx)
+{
+    return ctx->md_data;
+}
+
+int (*EVP_MD_CTX_update_fn(EVP_MD_CTX *ctx))(EVP_MD_CTX *ctx,
+                                             const void *data, size_t count)
+{
+    return ctx->update;
+}
+
+void EVP_MD_CTX_set_update_fn(EVP_MD_CTX *ctx,
+                              int (*update) (EVP_MD_CTX *ctx,
+                                             const void *data, size_t count))
+{
+    ctx->update = update;
+}
+
 void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags)
 {
     ctx->flags |= flags;
diff --git a/crypto/evp/evp_locl.h b/crypto/evp/evp_locl.h
index b70a54c..918ff0a 100644
--- a/crypto/evp/evp_locl.h
+++ b/crypto/evp/evp_locl.h
@@ -57,6 +57,20 @@
  *
  */
 
+/* EVP_MD_CTX related stuff */
+
+struct evp_md_ctx_st {
+    const EVP_MD *digest;
+    ENGINE *engine;             /* functional reference if 'digest' is
+                                 * ENGINE-provided */
+    unsigned long flags;
+    void *md_data;
+    /* Public key context for sign/verify */
+    EVP_PKEY_CTX *pctx;
+    /* Update function: usually copied from EVP_MD */
+    int (*update) (EVP_MD_CTX *ctx, const void *data, size_t count);
+} /* EVP_MD_CTX */ ;
+
 /* Macros to code block cipher wrappers */
 
 /* Wrapper functions for each cipher mode */
diff --git a/crypto/evp/m_md4.c b/crypto/evp/m_md4.c
index 80021b6..8987c42 100644
--- a/crypto/evp/m_md4.c
+++ b/crypto/evp/m_md4.c
@@ -68,20 +68,21 @@
 # ifndef OPENSSL_NO_RSA
 #  include <openssl/rsa.h>
 # endif
+# include "internal/evp_int.h"
 
 static int init(EVP_MD_CTX *ctx)
 {
-    return MD4_Init(ctx->md_data);
+    return MD4_Init(EVP_MD_CTX_md_data(ctx));
 }
 
 static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
 {
-    return MD4_Update(ctx->md_data, data, count);
+    return MD4_Update(EVP_MD_CTX_md_data(ctx), data, count);
 }
 
 static int final(EVP_MD_CTX *ctx, unsigned char *md)
 {
-    return MD4_Final(md, ctx->md_data);
+    return MD4_Final(md, EVP_MD_CTX_md_data(ctx));
 }
 
 static const EVP_MD md4_md = {
diff --git a/crypto/evp/m_md5.c b/crypto/evp/m_md5.c
index 4ada7d1..ad26604 100644
--- a/crypto/evp/m_md5.c
+++ b/crypto/evp/m_md5.c
@@ -68,20 +68,21 @@
 # ifndef OPENSSL_NO_RSA
 #  include <openssl/rsa.h>
 # endif
+# include "internal/evp_int.h"
 
 static int init(EVP_MD_CTX *ctx)
 {
-    return MD5_Init(ctx->md_data);
+    return MD5_Init(EVP_MD_CTX_md_data(ctx));
 }
 
 static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
 {
-    return MD5_Update(ctx->md_data, data, count);
+    return MD5_Update(EVP_MD_CTX_md_data(ctx), data, count);
 }
 
 static int final(EVP_MD_CTX *ctx, unsigned char *md)
 {
-    return MD5_Final(md, ctx->md_data);
+    return MD5_Final(md, EVP_MD_CTX_md_data(ctx));
 }
 
 static const EVP_MD md5_md = {
diff --git a/crypto/evp/m_md5_sha1.c b/crypto/evp/m_md5_sha1.c
index 22cd7ce..f5472a3 100644
--- a/crypto/evp/m_md5_sha1.c
+++ b/crypto/evp/m_md5_sha1.c
@@ -60,6 +60,7 @@
 # include <openssl/md5.h>
 # include <openssl/sha.h>
 # include "internal/cryptlib.h"
+# include "internal/evp_int.h"
 # ifndef OPENSSL_NO_RSA
 #  include <openssl/rsa.h>
 # endif
@@ -71,7 +72,7 @@ struct md5_sha1_ctx {
 
 static int init(EVP_MD_CTX *ctx)
 {
-    struct md5_sha1_ctx *mctx = ctx->md_data;
+    struct md5_sha1_ctx *mctx = EVP_MD_CTX_md_data(ctx);
     if (!MD5_Init(&mctx->md5))
         return 0;
     return SHA1_Init(&mctx->sha1);
@@ -79,7 +80,7 @@ static int init(EVP_MD_CTX *ctx)
 
 static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
 {
-    struct md5_sha1_ctx *mctx = ctx->md_data;
+    struct md5_sha1_ctx *mctx = EVP_MD_CTX_md_data(ctx);
     if (!MD5_Update(&mctx->md5, data, count))
         return 0;
     return SHA1_Update(&mctx->sha1, data, count);
@@ -87,7 +88,7 @@ static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
 
 static int final(EVP_MD_CTX *ctx, unsigned char *md)
 {
-    struct md5_sha1_ctx *mctx = ctx->md_data;
+    struct md5_sha1_ctx *mctx = EVP_MD_CTX_md_data(ctx);
     if (!MD5_Final(md, &mctx->md5))
         return 0;
     return SHA1_Final(md + MD5_DIGEST_LENGTH, &mctx->sha1);
@@ -98,7 +99,7 @@ static int ctrl(EVP_MD_CTX *ctx, int cmd, int mslen, void *ms)
     unsigned char padtmp[48];
     unsigned char md5tmp[MD5_DIGEST_LENGTH];
     unsigned char sha1tmp[SHA_DIGEST_LENGTH];
-    struct md5_sha1_ctx *mctx = ctx->md_data;
+    struct md5_sha1_ctx *mctx = EVP_MD_CTX_md_data(ctx);
 
     if (cmd != EVP_CTRL_SSL3_MASTER_SECRET)
         return 0;
diff --git a/crypto/evp/m_mdc2.c b/crypto/evp/m_mdc2.c
index ffd1b0e..8934b54 100644
--- a/crypto/evp/m_mdc2.c
+++ b/crypto/evp/m_mdc2.c
@@ -68,20 +68,21 @@
 # ifndef OPENSSL_NO_RSA
 #  include <openssl/rsa.h>
 # endif
+# include "internal/evp_int.h"
 
 static int init(EVP_MD_CTX *ctx)
 {
-    return MDC2_Init(ctx->md_data);
+    return MDC2_Init(EVP_MD_CTX_md_data(ctx));
 }
 
 static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
 {
-    return MDC2_Update(ctx->md_data, data, count);
+    return MDC2_Update(EVP_MD_CTX_md_data(ctx), data, count);
 }
 
 static int final(EVP_MD_CTX *ctx, unsigned char *md)
 {
-    return MDC2_Final(md, ctx->md_data);
+    return MDC2_Final(md, EVP_MD_CTX_md_data(ctx));
 }
 
 static const EVP_MD mdc2_md = {
diff --git a/crypto/evp/m_null.c b/crypto/evp/m_null.c
index c91f6cb..b649115 100644
--- a/crypto/evp/m_null.c
+++ b/crypto/evp/m_null.c
@@ -61,6 +61,7 @@
 #include <openssl/evp.h>
 #include <openssl/objects.h>
 #include <openssl/x509.h>
+#include "internal/evp_int.h"
 
 static int init(EVP_MD_CTX *ctx)
 {
diff --git a/crypto/evp/m_ripemd.c b/crypto/evp/m_ripemd.c
index f1c745c..faf09a1 100644
--- a/crypto/evp/m_ripemd.c
+++ b/crypto/evp/m_ripemd.c
@@ -68,20 +68,21 @@
 # ifndef OPENSSL_NO_RSA
 #  include <openssl/rsa.h>
 # endif
+# include "internal/evp_int.h"
 
 static int init(EVP_MD_CTX *ctx)
 {
-    return RIPEMD160_Init(ctx->md_data);
+    return RIPEMD160_Init(EVP_MD_CTX_md_data(ctx));
 }
 
 static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
 {
-    return RIPEMD160_Update(ctx->md_data, data, count);
+    return RIPEMD160_Update(EVP_MD_CTX_md_data(ctx), data, count);
 }
 
 static int final(EVP_MD_CTX *ctx, unsigned char *md)
 {
-    return RIPEMD160_Final(md, ctx->md_data);
+    return RIPEMD160_Final(md, EVP_MD_CTX_md_data(ctx));
 }
 
 static const EVP_MD ripemd160_md = {
diff --git a/crypto/evp/m_sha1.c b/crypto/evp/m_sha1.c
index c913cae..2f30c3c 100644
--- a/crypto/evp/m_sha1.c
+++ b/crypto/evp/m_sha1.c
@@ -65,20 +65,21 @@
 #ifndef OPENSSL_NO_RSA
 # include <openssl/rsa.h>
 #endif
+#include "internal/evp_int.h"
 
 static int init(EVP_MD_CTX *ctx)
 {
-    return SHA1_Init(ctx->md_data);
+    return SHA1_Init(EVP_MD_CTX_md_data(ctx));
 }
 
 static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
 {
-    return SHA1_Update(ctx->md_data, data, count);
+    return SHA1_Update(EVP_MD_CTX_md_data(ctx), data, count);
 }
 
 static int final(EVP_MD_CTX *ctx, unsigned char *md)
 {
-    return SHA1_Final(md, ctx->md_data);
+    return SHA1_Final(md, EVP_MD_CTX_md_data(ctx));
 }
 
 static int ctrl(EVP_MD_CTX *ctx, int cmd, int mslen, void *ms)
@@ -86,7 +87,7 @@ static int ctrl(EVP_MD_CTX *ctx, int cmd, int mslen, void *ms)
     unsigned char padtmp[40];
     unsigned char sha1tmp[SHA_DIGEST_LENGTH];
 
-    SHA_CTX *sha1 = ctx->md_data;
+    SHA_CTX *sha1 = EVP_MD_CTX_md_data(ctx);
 
     if (cmd != EVP_CTRL_SSL3_MASTER_SECRET)
         return 0;
@@ -157,12 +158,12 @@ const EVP_MD *EVP_sha1(void)
 
 static int init224(EVP_MD_CTX *ctx)
 {
-    return SHA224_Init(ctx->md_data);
+    return SHA224_Init(EVP_MD_CTX_md_data(ctx));
 }
 
 static int init256(EVP_MD_CTX *ctx)
 {
-    return SHA256_Init(ctx->md_data);
+    return SHA256_Init(EVP_MD_CTX_md_data(ctx));
 }
 
 /*
@@ -172,12 +173,12 @@ static int init256(EVP_MD_CTX *ctx)
  */
 static int update256(EVP_MD_CTX *ctx, const void *data, size_t count)
 {
-    return SHA256_Update(ctx->md_data, data, count);
+    return SHA256_Update(EVP_MD_CTX_md_data(ctx), data, count);
 }
 
 static int final256(EVP_MD_CTX *ctx, unsigned char *md)
 {
-    return SHA256_Final(md, ctx->md_data);
+    return SHA256_Final(md, EVP_MD_CTX_md_data(ctx));
 }
 
 static const EVP_MD sha224_md = {
@@ -220,23 +221,23 @@ const EVP_MD *EVP_sha256(void)
 
 static int init384(EVP_MD_CTX *ctx)
 {
-    return SHA384_Init(ctx->md_data);
+    return SHA384_Init(EVP_MD_CTX_md_data(ctx));
 }
 
 static int init512(EVP_MD_CTX *ctx)
 {
-    return SHA512_Init(ctx->md_data);
+    return SHA512_Init(EVP_MD_CTX_md_data(ctx));
 }
 
 /* See comment in SHA224/256 section */
 static int update512(EVP_MD_CTX *ctx, const void *data, size_t count)
 {
-    return SHA512_Update(ctx->md_data, data, count);
+    return SHA512_Update(EVP_MD_CTX_md_data(ctx), data, count);
 }
 
 static int final512(EVP_MD_CTX *ctx, unsigned char *md)
 {
-    return SHA512_Final(md, ctx->md_data);
+    return SHA512_Final(md, EVP_MD_CTX_md_data(ctx));
 }
 
 static const EVP_MD sha384_md = {
diff --git a/crypto/evp/m_sigver.c b/crypto/evp/m_sigver.c
index 258fd91..067d330 100644
--- a/crypto/evp/m_sigver.c
+++ b/crypto/evp/m_sigver.c
@@ -63,6 +63,7 @@
 #include <openssl/objects.h>
 #include <openssl/x509.h>
 #include "internal/evp_int.h"
+#include "evp_locl.h"
 
 static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
                           const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey,
@@ -157,16 +158,15 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
             else
                 r = EVP_DigestFinal_ex(ctx, md, &mdlen);
         } else {
-            EVP_MD_CTX tmp_ctx;
-            EVP_MD_CTX_init(&tmp_ctx);
-            if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx))
+            EVP_MD_CTX *tmp_ctx = EVP_MD_CTX_new();
+            if (tmp_ctx == NULL || !EVP_MD_CTX_copy_ex(tmp_ctx, ctx))
                 return 0;
             if (sctx)
-                r = tmp_ctx.pctx->pmeth->signctx(tmp_ctx.pctx,
-                                                 sigret, siglen, &tmp_ctx);
+                r = tmp_ctx->pctx->pmeth->signctx(tmp_ctx->pctx,
+                                                  sigret, siglen, tmp_ctx);
             else
-                r = EVP_DigestFinal_ex(&tmp_ctx, md, &mdlen);
-            EVP_MD_CTX_cleanup(&tmp_ctx);
+                r = EVP_DigestFinal_ex(tmp_ctx, md, &mdlen);
+            EVP_MD_CTX_free(tmp_ctx);
         }
         if (sctx || !r)
             return r;
@@ -203,16 +203,15 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
         } else
             r = EVP_DigestFinal_ex(ctx, md, &mdlen);
     } else {
-        EVP_MD_CTX tmp_ctx;
-        EVP_MD_CTX_init(&tmp_ctx);
-        if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx))
+        EVP_MD_CTX *tmp_ctx = EVP_MD_CTX_new();
+        if (tmp_ctx == NULL || !EVP_MD_CTX_copy_ex(tmp_ctx, ctx))
             return -1;
         if (vctx) {
-            r = tmp_ctx.pctx->pmeth->verifyctx(tmp_ctx.pctx,
-                                               sig, siglen, &tmp_ctx);
+            r = tmp_ctx->pctx->pmeth->verifyctx(tmp_ctx->pctx,
+                                                sig, siglen, tmp_ctx);
         } else
-            r = EVP_DigestFinal_ex(&tmp_ctx, md, &mdlen);
-        EVP_MD_CTX_cleanup(&tmp_ctx);
+            r = EVP_DigestFinal_ex(tmp_ctx, md, &mdlen);
+        EVP_MD_CTX_free(tmp_ctx);
     }
     if (vctx || !r)
         return r;
diff --git a/crypto/evp/m_wp.c b/crypto/evp/m_wp.c
index 9ab3c62..0a4a3a9 100644
--- a/crypto/evp/m_wp.c
+++ b/crypto/evp/m_wp.c
@@ -9,20 +9,21 @@
 # include <openssl/objects.h>
 # include <openssl/x509.h>
 # include <openssl/whrlpool.h>
+# include "internal/evp_int.h"
 
 static int init(EVP_MD_CTX *ctx)
 {
-    return WHIRLPOOL_Init(ctx->md_data);
+    return WHIRLPOOL_Init(EVP_MD_CTX_md_data(ctx));
 }
 
 static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
 {
-    return WHIRLPOOL_Update(ctx->md_data, data, count);
+    return WHIRLPOOL_Update(EVP_MD_CTX_md_data(ctx), data, count);
 }
 
 static int final(EVP_MD_CTX *ctx, unsigned char *md)
 {
-    return WHIRLPOOL_Final(md, ctx->md_data);
+    return WHIRLPOOL_Final(md, EVP_MD_CTX_md_data(ctx));
 }
 
 static const EVP_MD whirlpool_md = {
diff --git a/crypto/evp/names.c b/crypto/evp/names.c
index c7c4615..8d132e9 100644
--- a/crypto/evp/names.c
+++ b/crypto/evp/names.c
@@ -61,6 +61,7 @@
 #include <openssl/evp.h>
 #include <openssl/objects.h>
 #include <openssl/x509.h>
+#include "internal/evp_int.h"
 
 int EVP_add_cipher(const EVP_CIPHER *c)
 {
diff --git a/crypto/evp/p5_crpt.c b/crypto/evp/p5_crpt.c
index 2d37d08..d27d83f 100644
--- a/crypto/evp/p5_crpt.c
+++ b/crypto/evp/p5_crpt.c
@@ -75,7 +75,7 @@ int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen,
                        ASN1_TYPE *param, const EVP_CIPHER *cipher,
                        const EVP_MD *md, int en_de)
 {
-    EVP_MD_CTX ctx;
+    EVP_MD_CTX *ctx;
     unsigned char md_tmp[EVP_MAX_MD_SIZE];
     unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
     int i;
@@ -84,7 +84,6 @@ int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen,
     unsigned char *salt;
     int mdsize;
     int rv = 0;
-    EVP_MD_CTX_init(&ctx);
 
     /* Extract useful info from parameter */
     if (param == NULL || param->type != V_ASN1_SEQUENCE ||
@@ -111,24 +110,30 @@ int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen,
     else if (passlen == -1)
         passlen = strlen(pass);
 
-    if (!EVP_DigestInit_ex(&ctx, md, NULL))
+    ctx = EVP_MD_CTX_new();
+    if (ctx == NULL) {
+        EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN, ERR_R_MALLOC_FAILURE);
         goto err;
-    if (!EVP_DigestUpdate(&ctx, pass, passlen))
+    }
+
+    if (!EVP_DigestInit_ex(ctx, md, NULL))
+        goto err;
+    if (!EVP_DigestUpdate(ctx, pass, passlen))
         goto err;
-    if (!EVP_DigestUpdate(&ctx, salt, saltlen))
+    if (!EVP_DigestUpdate(ctx, salt, saltlen))
         goto err;
     PBEPARAM_free(pbe);
-    if (!EVP_DigestFinal_ex(&ctx, md_tmp, NULL))
+    if (!EVP_DigestFinal_ex(ctx, md_tmp, NULL))
         goto err;
     mdsize = EVP_MD_size(md);
     if (mdsize < 0)
         return 0;
     for (i = 1; i < iter; i++) {
-        if (!EVP_DigestInit_ex(&ctx, md, NULL))
+        if (!EVP_DigestInit_ex(ctx, md, NULL))
             goto err;
-        if (!EVP_DigestUpdate(&ctx, md_tmp, mdsize))
+        if (!EVP_DigestUpdate(ctx, md_tmp, mdsize))
             goto err;
-        if (!EVP_DigestFinal_ex(&ctx, md_tmp, NULL))
+        if (!EVP_DigestFinal_ex(ctx, md_tmp, NULL))
             goto err;
     }
     OPENSSL_assert(EVP_CIPHER_key_length(cipher) <= (int)sizeof(md_tmp));
@@ -143,6 +148,6 @@ int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen,
     OPENSSL_cleanse(iv, EVP_MAX_IV_LENGTH);
     rv = 1;
  err:
-    EVP_MD_CTX_cleanup(&ctx);
+    EVP_MD_CTX_free(ctx);
     return rv;
 }
diff --git a/crypto/evp/p5_crpt2.c b/crypto/evp/p5_crpt2.c
index 4986a21..0f5b82b 100644
--- a/crypto/evp/p5_crpt2.c
+++ b/crypto/evp/p5_crpt2.c
@@ -85,21 +85,28 @@ int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
     unsigned char digtmp[EVP_MAX_MD_SIZE], *p, itmp[4];
     int cplen, j, k, tkeylen, mdlen;
     unsigned long i = 1;
-    HMAC_CTX hctx_tpl, hctx;
+    HMAC_CTX *hctx_tpl = NULL, *hctx = NULL;
 
     mdlen = EVP_MD_size(digest);
     if (mdlen < 0)
         return 0;
 
-    HMAC_CTX_init(&hctx_tpl);
+    hctx_tpl = HMAC_CTX_new();
+    if (hctx_tpl == NULL)
+        return 0;
     p = out;
     tkeylen = keylen;
     if (!pass)
         passlen = 0;
     else if (passlen == -1)
         passlen = strlen(pass);
-    if (!HMAC_Init_ex(&hctx_tpl, pass, passlen, digest, NULL)) {
-        HMAC_CTX_cleanup(&hctx_tpl);
+    if (!HMAC_Init_ex(hctx_tpl, pass, passlen, digest, NULL)) {
+        HMAC_CTX_free(hctx_tpl);
+        return 0;
+    }
+    hctx = HMAC_CTX_new();
+    if (hctx == NULL) {
+        HMAC_CTX_free(hctx_tpl);
         return 0;
     }
     while (tkeylen) {
@@ -115,31 +122,33 @@ int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
         itmp[1] = (unsigned char)((i >> 16) & 0xff);
         itmp[2] = (unsigned char)((i >> 8) & 0xff);
         itmp[3] = (unsigned char)(i & 0xff);
-        if (!HMAC_CTX_copy(&hctx, &hctx_tpl)) {
-            HMAC_CTX_cleanup(&hctx_tpl);
+        if (!HMAC_CTX_copy(hctx, hctx_tpl)) {
+            HMAC_CTX_free(hctx);
+            HMAC_CTX_free(hctx_tpl);
             return 0;
         }
-        if (!HMAC_Update(&hctx, salt, saltlen)
-            || !HMAC_Update(&hctx, itmp, 4)
-            || !HMAC_Final(&hctx, digtmp, NULL)) {
-            HMAC_CTX_cleanup(&hctx_tpl);
-            HMAC_CTX_cleanup(&hctx);
+        if (!HMAC_Update(hctx, salt, saltlen)
+            || !HMAC_Update(hctx, itmp, 4)
+            || !HMAC_Final(hctx, digtmp, NULL)) {
+            HMAC_CTX_free(hctx);
+            HMAC_CTX_free(hctx_tpl);
             return 0;
         }
-        HMAC_CTX_cleanup(&hctx);
+        HMAC_CTX_reset(hctx);
         memcpy(p, digtmp, cplen);
         for (j = 1; j < iter; j++) {
-            if (!HMAC_CTX_copy(&hctx, &hctx_tpl)) {
-                HMAC_CTX_cleanup(&hctx_tpl);
+            if (!HMAC_CTX_copy(hctx, hctx_tpl)) {
+                HMAC_CTX_free(hctx);
+                HMAC_CTX_free(hctx_tpl);
                 return 0;
             }
-            if (!HMAC_Update(&hctx, digtmp, mdlen)
-                || !HMAC_Final(&hctx, digtmp, NULL)) {
-                HMAC_CTX_cleanup(&hctx_tpl);
-                HMAC_CTX_cleanup(&hctx);
+            if (!HMAC_Update(hctx, digtmp, mdlen)
+                || !HMAC_Final(hctx, digtmp, NULL)) {
+                HMAC_CTX_free(hctx);
+                HMAC_CTX_free(hctx_tpl);
                 return 0;
             }
-            HMAC_CTX_cleanup(&hctx);
+            HMAC_CTX_reset(hctx);
             for (k = 0; k < cplen; k++)
                 p[k] ^= digtmp[k];
         }
@@ -147,7 +156,8 @@ int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
         i++;
         p += cplen;
     }
-    HMAC_CTX_cleanup(&hctx_tpl);
+    HMAC_CTX_free(hctx);
+    HMAC_CTX_free(hctx_tpl);
 # ifdef DEBUG_PKCS5V2
     fprintf(stderr, "Password:\n");
     h__dump(pass, passlen);
diff --git a/crypto/evp/p_sign.c b/crypto/evp/p_sign.c
index 808d0de..c5e479e 100644
--- a/crypto/evp/p_sign.c
+++ b/crypto/evp/p_sign.c
@@ -61,6 +61,7 @@
 #include <openssl/evp.h>
 #include <openssl/objects.h>
 #include <openssl/x509.h>
+#include "internal/evp_int.h"
 
 int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
                   unsigned int *siglen, EVP_PKEY *pkey)
@@ -72,17 +73,20 @@ int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
     EVP_PKEY_CTX *pkctx = NULL;
 
     *siglen = 0;
-    if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE) {
+    if (EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_FINALISE)) {
         if (!EVP_DigestFinal_ex(ctx, m, &m_len))
             goto err;
     } else {
         int rv = 0;
-        EVP_MD_CTX tmp_ctx;
-        EVP_MD_CTX_init(&tmp_ctx);
-        rv = EVP_MD_CTX_copy_ex(&tmp_ctx, ctx);
+        EVP_MD_CTX *tmp_ctx = EVP_MD_CTX_new();
+        if (tmp_ctx == NULL) {
+            EVPerr(EVP_F_EVP_SIGNFINAL, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+        rv = EVP_MD_CTX_copy_ex(tmp_ctx, ctx);
         if (rv)
-            rv = EVP_DigestFinal_ex(&tmp_ctx, m, &m_len);
-        EVP_MD_CTX_cleanup(&tmp_ctx);
+            rv = EVP_DigestFinal_ex(tmp_ctx, m, &m_len);
+        EVP_MD_CTX_free(tmp_ctx);
         if (!rv)
             return 0;
     }
@@ -94,13 +98,13 @@ int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
         goto err;
     if (EVP_PKEY_sign_init(pkctx) <= 0)
         goto err;
-    if (EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) <= 0)
+    if (EVP_PKEY_CTX_set_signature_md(pkctx, EVP_MD_CTX_md(ctx)) <= 0)
         goto err;
     if (EVP_PKEY_sign(pkctx, sigret, &sltmp, m, m_len) <= 0)
         goto err;
     *siglen = sltmp;
     i = 1;
  err:
-        EVP_PKEY_CTX_free(pkctx);
-        return i;
+    EVP_PKEY_CTX_free(pkctx);
+    return i;
 }
diff --git a/crypto/evp/p_verify.c b/crypto/evp/p_verify.c
index 9802dcc..32ec0de 100644
--- a/crypto/evp/p_verify.c
+++ b/crypto/evp/p_verify.c
@@ -61,6 +61,7 @@
 #include <openssl/evp.h>
 #include <openssl/objects.h>
 #include <openssl/x509.h>
+#include "internal/evp_int.h"
 
 int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf,
                     unsigned int siglen, EVP_PKEY *pkey)
@@ -70,17 +71,20 @@ int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf,
     int i = 0;
     EVP_PKEY_CTX *pkctx = NULL;
 
-    if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE) {
+    if (EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_FINALISE)) {
         if (!EVP_DigestFinal_ex(ctx, m, &m_len))
             goto err;
     } else {
         int rv = 0;
-        EVP_MD_CTX tmp_ctx;
-        EVP_MD_CTX_init(&tmp_ctx);
-        rv = EVP_MD_CTX_copy_ex(&tmp_ctx, ctx);
+        EVP_MD_CTX *tmp_ctx = EVP_MD_CTX_new();
+        if (tmp_ctx == NULL) {
+            EVPerr(EVP_F_EVP_VERIFYFINAL, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+        rv = EVP_MD_CTX_copy_ex(tmp_ctx, ctx);
         if (rv)
-            rv = EVP_DigestFinal_ex(&tmp_ctx, m, &m_len);
-        EVP_MD_CTX_cleanup(&tmp_ctx);
+            rv = EVP_DigestFinal_ex(tmp_ctx, m, &m_len);
+        EVP_MD_CTX_free(tmp_ctx);
         if (!rv)
             return 0;
     }
@@ -91,7 +95,7 @@ int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf,
         goto err;
     if (EVP_PKEY_verify_init(pkctx) <= 0)
         goto err;
-    if (EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) <= 0)
+    if (EVP_PKEY_CTX_set_signature_md(pkctx, EVP_MD_CTX_md(ctx)) <= 0)
         goto err;
     i = EVP_PKEY_verify(pkctx, sigbuf, siglen, m, m_len);
  err:
diff --git a/crypto/hmac/Makefile b/crypto/hmac/Makefile
index 934631a..a16e620 100644
--- a/crypto/hmac/Makefile
+++ b/crypto/hmac/Makefile
@@ -95,3 +95,4 @@ hmac.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 hmac.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 hmac.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
 hmac.o: ../../include/openssl/symhacks.h ../include/internal/cryptlib.h hmac.c
+hmac.o: hmac_lcl.h
diff --git a/crypto/hmac/hm_pmeth.c b/crypto/hmac/hm_pmeth.c
index e06a1db..41013bc 100644
--- a/crypto/hmac/hm_pmeth.c
+++ b/crypto/hmac/hm_pmeth.c
@@ -69,7 +69,7 @@
 typedef struct {
     const EVP_MD *md;           /* MD for HMAC use */
     ASN1_OCTET_STRING ktmp;     /* Temp storage for key */
-    HMAC_CTX ctx;
+    HMAC_CTX *ctx;
 } HMAC_PKEY_CTX;
 
 static int pkey_hmac_init(EVP_PKEY_CTX *ctx)
@@ -80,7 +80,7 @@ static int pkey_hmac_init(EVP_PKEY_CTX *ctx)
     if (hctx == NULL)
         return 0;
     hctx->ktmp.type = V_ASN1_OCTET_STRING;
-    HMAC_CTX_init(&hctx->ctx);
+    hctx->ctx = HMAC_CTX_new();
 
     ctx->data = hctx;
     ctx->keygen_info_count = 0;
@@ -96,8 +96,7 @@ static int pkey_hmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
     sctx = src->data;
     dctx = dst->data;
     dctx->md = sctx->md;
-    HMAC_CTX_init(&dctx->ctx);
-    if (!HMAC_CTX_copy(&dctx->ctx, &sctx->ctx))
+    if (!HMAC_CTX_copy(dctx->ctx, sctx->ctx))
         return 0;
     if (sctx->ktmp.data) {
         if (!ASN1_OCTET_STRING_set(&dctx->ktmp,
@@ -111,9 +110,12 @@ static void pkey_hmac_cleanup(EVP_PKEY_CTX *ctx)
 {
     HMAC_PKEY_CTX *hctx = ctx->data;
 
-    HMAC_CTX_cleanup(&hctx->ctx);
-    OPENSSL_clear_free(hctx->ktmp.data, hctx->ktmp.length);
-    OPENSSL_free(hctx);
+    if (hctx != NULL) {
+        HMAC_CTX_free(hctx->ctx);
+        OPENSSL_clear_free(hctx->ktmp.data, hctx->ktmp.length);
+        OPENSSL_free(hctx);
+        ctx->data = NULL;
+    }
 }
 
 static int pkey_hmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
@@ -132,8 +134,8 @@ static int pkey_hmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
 
 static int int_update(EVP_MD_CTX *ctx, const void *data, size_t count)
 {
-    HMAC_PKEY_CTX *hctx = ctx->pctx->data;
-    if (!HMAC_Update(&hctx->ctx, data, count))
+    HMAC_PKEY_CTX *hctx = EVP_MD_CTX_pkey_ctx(ctx)->data;
+    if (!HMAC_Update(hctx->ctx, data, count))
         return 0;
     return 1;
 }
@@ -141,9 +143,10 @@ static int int_update(EVP_MD_CTX *ctx, const void *data, size_t count)
 static int hmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
 {
     HMAC_PKEY_CTX *hctx = ctx->data;
-    HMAC_CTX_set_flags(&hctx->ctx, mctx->flags & ~EVP_MD_CTX_FLAG_NO_INIT);
+    HMAC_CTX_set_flags(hctx->ctx,
+                       EVP_MD_CTX_test_flags(mctx, ~EVP_MD_CTX_FLAG_NO_INIT));
     EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT);
-    mctx->update = int_update;
+    EVP_MD_CTX_set_update_fn(mctx, int_update);
     return 1;
 }
 
@@ -160,7 +163,7 @@ static int hmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
     if (!sig)
         return 1;
 
-    if (!HMAC_Final(&hctx->ctx, sig, &hlen))
+    if (!HMAC_Final(hctx->ctx, sig, &hlen))
         return 0;
     *siglen = (size_t)hlen;
     return 1;
@@ -185,7 +188,7 @@ static int pkey_hmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
 
     case EVP_PKEY_CTRL_DIGESTINIT:
         key = (ASN1_OCTET_STRING *)ctx->pkey->pkey.ptr;
-        if (!HMAC_Init_ex(&hctx->ctx, key->data, key->length, hctx->md,
+        if (!HMAC_Init_ex(hctx->ctx, key->data, key->length, hctx->md,
                           ctx->engine))
             return 0;
         break;
diff --git a/crypto/hmac/hmac.c b/crypto/hmac/hmac.c
index 7699b0b..3bc93a8 100644
--- a/crypto/hmac/hmac.c
+++ b/crypto/hmac/hmac.c
@@ -61,6 +61,7 @@
 #include <string.h>
 #include "internal/cryptlib.h"
 #include <openssl/hmac.h>
+#include "hmac_lcl.h"
 
 int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
                  const EVP_MD *md, ENGINE *impl)
@@ -83,14 +84,14 @@ int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
 
     if (key != NULL) {
         reset = 1;
-        j = M_EVP_MD_block_size(md);
+        j = EVP_MD_block_size(md);
         OPENSSL_assert(j <= (int)sizeof(ctx->key));
         if (j < len) {
-            if (!EVP_DigestInit_ex(&ctx->md_ctx, md, impl))
+            if (!EVP_DigestInit_ex(ctx->md_ctx, md, impl))
                 goto err;
-            if (!EVP_DigestUpdate(&ctx->md_ctx, key, len))
+            if (!EVP_DigestUpdate(ctx->md_ctx, key, len))
                 goto err;
-            if (!EVP_DigestFinal_ex(&(ctx->md_ctx), ctx->key,
+            if (!EVP_DigestFinal_ex(ctx->md_ctx, ctx->key,
                                     &ctx->key_length))
                 goto err;
         } else {
@@ -107,19 +108,19 @@ int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
     if (reset) {
         for (i = 0; i < HMAC_MAX_MD_CBLOCK; i++)
             pad[i] = 0x36 ^ ctx->key[i];
-        if (!EVP_DigestInit_ex(&ctx->i_ctx, md, impl))
+        if (!EVP_DigestInit_ex(ctx->i_ctx, md, impl))
             goto err;
-        if (!EVP_DigestUpdate(&ctx->i_ctx, pad, M_EVP_MD_block_size(md)))
+        if (!EVP_DigestUpdate(ctx->i_ctx, pad, EVP_MD_block_size(md)))
             goto err;
 
         for (i = 0; i < HMAC_MAX_MD_CBLOCK; i++)
             pad[i] = 0x5c ^ ctx->key[i];
-        if (!EVP_DigestInit_ex(&ctx->o_ctx, md, impl))
+        if (!EVP_DigestInit_ex(ctx->o_ctx, md, impl))
             goto err;
-        if (!EVP_DigestUpdate(&ctx->o_ctx, pad, M_EVP_MD_block_size(md)))
+        if (!EVP_DigestUpdate(ctx->o_ctx, pad, EVP_MD_block_size(md)))
             goto err;
     }
-    if (!EVP_MD_CTX_copy_ex(&ctx->md_ctx, &ctx->i_ctx))
+    if (!EVP_MD_CTX_copy_ex(ctx->md_ctx, ctx->i_ctx))
         goto err;
     return 1;
  err:
@@ -130,7 +131,7 @@ int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
 int HMAC_Init(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md)
 {
     if (key && md)
-        HMAC_CTX_init(ctx);
+        HMAC_CTX_reset(ctx);
     return HMAC_Init_ex(ctx, key, len, md, NULL);
 }
 #endif
@@ -139,7 +140,7 @@ int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len)
 {
     if (!ctx->md)
         return 0;
-    return EVP_DigestUpdate(&ctx->md_ctx, data, len);
+    return EVP_DigestUpdate(ctx->md_ctx, data, len);
 }
 
 int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len)
@@ -150,78 +151,124 @@ int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len)
     if (!ctx->md)
         goto err;
 
-    if (!EVP_DigestFinal_ex(&ctx->md_ctx, buf, &i))
+    if (!EVP_DigestFinal_ex(ctx->md_ctx, buf, &i))
         goto err;
-    if (!EVP_MD_CTX_copy_ex(&ctx->md_ctx, &ctx->o_ctx))
+    if (!EVP_MD_CTX_copy_ex(ctx->md_ctx, ctx->o_ctx))
         goto err;
-    if (!EVP_DigestUpdate(&ctx->md_ctx, buf, i))
+    if (!EVP_DigestUpdate(ctx->md_ctx, buf, i))
         goto err;
-    if (!EVP_DigestFinal_ex(&ctx->md_ctx, md, len))
+    if (!EVP_DigestFinal_ex(ctx->md_ctx, md, len))
         goto err;
     return 1;
  err:
     return 0;
 }
 
-void HMAC_CTX_init(HMAC_CTX *ctx)
+size_t HMAC_size(HMAC_CTX *ctx)
 {
-    EVP_MD_CTX_init(&ctx->i_ctx);
-    EVP_MD_CTX_init(&ctx->o_ctx);
-    EVP_MD_CTX_init(&ctx->md_ctx);
+    return EVP_MD_size((ctx)->md);
+}
+
+HMAC_CTX *HMAC_CTX_new(void)
+{
+    HMAC_CTX *ctx = (HMAC_CTX *)OPENSSL_zalloc(sizeof(HMAC_CTX));
+    if (ctx)
+        if (!HMAC_CTX_reset(ctx)) {
+            HMAC_CTX_free(ctx);
+            ctx = NULL;
+        }
+    return ctx;
+}
+
+static void hmac_ctx_cleanup(HMAC_CTX *ctx)
+{
+    EVP_MD_CTX_reset(ctx->i_ctx);
+    EVP_MD_CTX_reset(ctx->o_ctx);
+    EVP_MD_CTX_reset(ctx->md_ctx);
+    ctx->md = NULL;
+    ctx->key_length = 0;
+    memset(ctx->key, 0, sizeof(HMAC_MAX_MD_CBLOCK));
+}
+
+void HMAC_CTX_free(HMAC_CTX *ctx)
+{
+    if (ctx != NULL) {
+        hmac_ctx_cleanup(ctx);
+        EVP_MD_CTX_free(ctx->i_ctx);
+        EVP_MD_CTX_free(ctx->o_ctx);
+        EVP_MD_CTX_free(ctx->md_ctx);
+        OPENSSL_free(ctx);
+    }
+}
+
+int HMAC_CTX_reset(HMAC_CTX *ctx)
+{
+    hmac_ctx_cleanup(ctx);
+    if (ctx->i_ctx == NULL)
+        ctx->i_ctx = EVP_MD_CTX_new();
+    if (ctx->i_ctx == NULL)
+        goto err;
+    if (ctx->o_ctx == NULL)
+        ctx->o_ctx = EVP_MD_CTX_new();
+    if (ctx->o_ctx == NULL)
+        goto err;
+    if (ctx->md_ctx == NULL)
+        ctx->md_ctx = EVP_MD_CTX_new();
+    if (ctx->md_ctx == NULL)
+        goto err;
     ctx->md = NULL;
+    return 1;
+ err:
+    hmac_ctx_cleanup(ctx);
+    return 0;
 }
 
 int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx)
 {
-    HMAC_CTX_init(dctx);
-    if (!EVP_MD_CTX_copy_ex(&dctx->i_ctx, &sctx->i_ctx))
+    if (!HMAC_CTX_reset(dctx))
+        goto err;
+    if (!EVP_MD_CTX_copy_ex(dctx->i_ctx, sctx->i_ctx))
         goto err;
-    if (!EVP_MD_CTX_copy_ex(&dctx->o_ctx, &sctx->o_ctx))
+    if (!EVP_MD_CTX_copy_ex(dctx->o_ctx, sctx->o_ctx))
         goto err;
-    if (!EVP_MD_CTX_copy_ex(&dctx->md_ctx, &sctx->md_ctx))
+    if (!EVP_MD_CTX_copy_ex(dctx->md_ctx, sctx->md_ctx))
         goto err;
     memcpy(dctx->key, sctx->key, HMAC_MAX_MD_CBLOCK);
     dctx->key_length = sctx->key_length;
     dctx->md = sctx->md;
     return 1;
  err:
+    hmac_ctx_cleanup(dctx);
     return 0;
 }
 
-void HMAC_CTX_cleanup(HMAC_CTX *ctx)
-{
-    EVP_MD_CTX_cleanup(&ctx->i_ctx);
-    EVP_MD_CTX_cleanup(&ctx->o_ctx);
-    EVP_MD_CTX_cleanup(&ctx->md_ctx);
-    memset(ctx, 0, sizeof(*ctx));
-}
-
 unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len,
                     const unsigned char *d, size_t n, unsigned char *md,
                     unsigned int *md_len)
 {
-    HMAC_CTX c;
+    HMAC_CTX *c = NULL;
     static unsigned char m[EVP_MAX_MD_SIZE];
 
     if (md == NULL)
         md = m;
-    HMAC_CTX_init(&c);
-    if (!HMAC_Init_ex(&c, key, key_len, evp_md, NULL))
+    if ((c = HMAC_CTX_new()) == NULL)
+        goto err;
+    if (!HMAC_Init_ex(c, key, key_len, evp_md, NULL))
         goto err;
-    if (!HMAC_Update(&c, d, n))
+    if (!HMAC_Update(c, d, n))
         goto err;
-    if (!HMAC_Final(&c, md, md_len))
+    if (!HMAC_Final(c, md, md_len))
         goto err;
-    HMAC_CTX_cleanup(&c);
+    HMAC_CTX_free(c);
     return md;
  err:
-    HMAC_CTX_cleanup(&c);
+    HMAC_CTX_free(c);
     return NULL;
 }
 
 void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags)
 {
-    M_EVP_MD_CTX_set_flags(&ctx->i_ctx, flags);
-    M_EVP_MD_CTX_set_flags(&ctx->o_ctx, flags);
-    M_EVP_MD_CTX_set_flags(&ctx->md_ctx, flags);
+    EVP_MD_CTX_set_flags(ctx->i_ctx, flags);
+    EVP_MD_CTX_set_flags(ctx->o_ctx, flags);
+    EVP_MD_CTX_set_flags(ctx->md_ctx, flags);
 }
diff --git a/include/openssl/ssl2.h b/crypto/hmac/hmac_lcl.h
similarity index 90%
copy from include/openssl/ssl2.h
copy to crypto/hmac/hmac_lcl.h
index 64e1b14..b14607d 100644
--- a/include/openssl/ssl2.h
+++ b/crypto/hmac/hmac_lcl.h
@@ -1,4 +1,4 @@
-/* ssl/ssl2.h */
+/* crypto/hmac/hmac.h */
 /* Copyright (C) 1995-1998 Eric Young (eay at cryptsoft.com)
  * All rights reserved.
  *
@@ -55,19 +55,23 @@
  * copied and put under another distribution licence
  * [including the GNU Public Licence.]
  */
-
-#ifndef HEADER_SSL2_H
-# define HEADER_SSL2_H
+#ifndef HEADER_HMAC_LCL_H
+# define HEADER_HMAC_LCL_H
 
 #ifdef  __cplusplus
 extern "C" {
 #endif
-
-# define SSL2_VERSION            0x0002
-
-# define SSL2_MT_CLIENT_HELLO            1
-
-#ifdef  __cplusplus
+#if 0                            /* emacs indentation fix */
 }
 #endif
+
+typedef struct hmac_ctx_st {
+    const EVP_MD *md;
+    EVP_MD_CTX *md_ctx;
+    EVP_MD_CTX *i_ctx;
+    EVP_MD_CTX *o_ctx;
+    unsigned int key_length;
+    unsigned char key[HMAC_MAX_MD_CBLOCK];
+} HMAC_CTX;
+
 #endif
diff --git a/crypto/include/internal/evp_int.h b/crypto/include/internal/evp_int.h
index 218aede..4372d4b 100644
--- a/crypto/include/internal/evp_int.h
+++ b/crypto/include/internal/evp_int.h
@@ -129,3 +129,20 @@ extern const EVP_PKEY_METHOD dsa_pkey_meth;
 extern const EVP_PKEY_METHOD ec_pkey_meth;
 extern const EVP_PKEY_METHOD hmac_pkey_meth;
 extern const EVP_PKEY_METHOD rsa_pkey_meth;
+
+struct evp_md_st {
+    int type;
+    int pkey_type;
+    int md_size;
+    unsigned long flags;
+    int (*init) (EVP_MD_CTX *ctx);
+    int (*update) (EVP_MD_CTX *ctx, const void *data, size_t count);
+    int (*final) (EVP_MD_CTX *ctx, unsigned char *md);
+    int (*copy) (EVP_MD_CTX *to, const EVP_MD_CTX *from);
+    int (*cleanup) (EVP_MD_CTX *ctx);
+    int block_size;
+    int ctx_size;               /* how big does the ctx->md_data need to be */
+    /* control function */
+    int (*md_ctrl) (EVP_MD_CTX *ctx, int cmd, int p1, void *p2);
+} /* EVP_MD */ ;
+
diff --git a/crypto/pem/pem_seal.c b/crypto/pem/pem_seal.c
index e8ea1b0..d0db777 100644
--- a/crypto/pem/pem_seal.c
+++ b/crypto/pem/pem_seal.c
@@ -93,8 +93,8 @@ int PEM_SealInit(PEM_ENCODE_SEAL_CTX *ctx, EVP_CIPHER *type, EVP_MD *md_type,
 
     EVP_EncodeInit(&ctx->encode);
 
-    EVP_MD_CTX_init(&ctx->md);
-    if (!EVP_SignInit(&ctx->md, md_type))
+    ctx->md = EVP_MD_CTX_new();
+    if (!EVP_SignInit(ctx->md, md_type))
         goto err;
 
     EVP_CIPHER_CTX_init(&ctx->cipher);
@@ -124,7 +124,7 @@ int PEM_SealUpdate(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *out, int *outl,
     int i, j;
 
     *outl = 0;
-    if (!EVP_SignUpdate(&ctx->md, in, inl))
+    if (!EVP_SignUpdate(ctx->md, in, inl))
         return 0;
     for (;;) {
         if (inl <= 0)
@@ -172,13 +172,13 @@ int PEM_SealFinal(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *sig, int *sigl,
     EVP_EncodeFinal(&ctx->encode, out, &j);
     *outl += j;
 
-    if (!EVP_SignFinal(&ctx->md, s, &i, priv))
+    if (!EVP_SignFinal(ctx->md, s, &i, priv))
         goto err;
     *sigl = EVP_EncodeBlock(sig, s, i);
 
     ret = 1;
  err:
-    EVP_MD_CTX_cleanup(&ctx->md);
+    EVP_MD_CTX_free(ctx->md);
     EVP_CIPHER_CTX_cleanup(&ctx->cipher);
     OPENSSL_free(s);
     return (ret);
diff --git a/crypto/pem/pvkfmt.c b/crypto/pem/pvkfmt.c
index 50f19f3..c95967c 100644
--- a/crypto/pem/pvkfmt.c
+++ b/crypto/pem/pvkfmt.c
@@ -650,16 +650,16 @@ static int derive_pvk_key(unsigned char *key,
                           const unsigned char *salt, unsigned int saltlen,
                           const unsigned char *pass, int passlen)
 {
-    EVP_MD_CTX mctx;
+    EVP_MD_CTX *mctx = EVP_MD_CTX_new();;
     int rv = 1;
-    EVP_MD_CTX_init(&mctx);
-    if (!EVP_DigestInit_ex(&mctx, EVP_sha1(), NULL)
-        || !EVP_DigestUpdate(&mctx, salt, saltlen)
-        || !EVP_DigestUpdate(&mctx, pass, passlen)
-        || !EVP_DigestFinal_ex(&mctx, key, NULL))
+    if (mctx == NULL
+        || !EVP_DigestInit_ex(mctx, EVP_sha1(), NULL)
+        || !EVP_DigestUpdate(mctx, salt, saltlen)
+        || !EVP_DigestUpdate(mctx, pass, passlen)
+        || !EVP_DigestFinal_ex(mctx, key, NULL))
         rv = 0;
 
-    EVP_MD_CTX_cleanup(&mctx);
+    EVP_MD_CTX_free(mctx);
     return rv;
 }
 
diff --git a/crypto/pkcs12/p12_key.c b/crypto/pkcs12/p12_key.c
index fe378d7..3efdd4a 100644
--- a/crypto/pkcs12/p12_key.c
+++ b/crypto/pkcs12/p12_key.c
@@ -109,13 +109,16 @@ int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt,
     int i, j, u, v;
     int ret = 0;
     BIGNUM *Ij, *Bpl1;          /* These hold Ij and B + 1 */
-    EVP_MD_CTX ctx;
+    EVP_MD_CTX *ctx;
 #ifdef  DEBUG_KEYGEN
     unsigned char *tmpout = out;
     int tmpn = n;
 #endif
 
-    EVP_MD_CTX_init(&ctx);
+    ctx = EVP_MD_CTX_new();
+    if (ctx == NULL)
+        goto err;
+
 #ifdef  DEBUG_KEYGEN
     fprintf(stderr, "KEYGEN DEBUG\n");
     fprintf(stderr, "ID %d, ITER %d\n", id, iter);
@@ -151,15 +154,15 @@ int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt,
     for (i = 0; i < Plen; i++)
         *p++ = pass[i % passlen];
     for (;;) {
-        if (!EVP_DigestInit_ex(&ctx, md_type, NULL)
-            || !EVP_DigestUpdate(&ctx, D, v)
-            || !EVP_DigestUpdate(&ctx, I, Ilen)
-            || !EVP_DigestFinal_ex(&ctx, Ai, NULL))
+        if (!EVP_DigestInit_ex(ctx, md_type, NULL)
+            || !EVP_DigestUpdate(ctx, D, v)
+            || !EVP_DigestUpdate(ctx, I, Ilen)
+            || !EVP_DigestFinal_ex(ctx, Ai, NULL))
             goto err;
         for (j = 1; j < iter; j++) {
-            if (!EVP_DigestInit_ex(&ctx, md_type, NULL)
-                || !EVP_DigestUpdate(&ctx, Ai, u)
-                || !EVP_DigestFinal_ex(&ctx, Ai, NULL))
+            if (!EVP_DigestInit_ex(ctx, md_type, NULL)
+                || !EVP_DigestUpdate(ctx, Ai, u)
+                || !EVP_DigestFinal_ex(ctx, Ai, NULL))
                 goto err;
         }
         memcpy(out, Ai, min(n, u));
@@ -215,7 +218,7 @@ int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt,
     OPENSSL_free(I);
     BN_free(Ij);
     BN_free(Bpl1);
-    EVP_MD_CTX_cleanup(&ctx);
+    EVP_MD_CTX_free(ctx);
     return ret;
 }
 
diff --git a/crypto/pkcs12/p12_mutl.c b/crypto/pkcs12/p12_mutl.c
index 4cf68e1..fda2bc9 100644
--- a/crypto/pkcs12/p12_mutl.c
+++ b/crypto/pkcs12/p12_mutl.c
@@ -59,7 +59,7 @@
 
 # include <stdio.h>
 # include "internal/cryptlib.h"
-#include <openssl/crypto.h>
+# include <openssl/crypto.h>
 # include <openssl/hmac.h>
 # include <openssl/rand.h>
 # include <openssl/pkcs12.h>
@@ -91,7 +91,7 @@ int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen,
                    unsigned char *mac, unsigned int *maclen)
 {
     const EVP_MD *md_type;
-    HMAC_CTX hmac;
+    HMAC_CTX *hmac = NULL;
     unsigned char key[EVP_MAX_MD_SIZE], *salt;
     int saltlen, iter;
     int md_size = 0;
@@ -133,15 +133,15 @@ int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen,
         PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_KEY_GEN_ERROR);
         return 0;
     }
-    HMAC_CTX_init(&hmac);
-    if (!HMAC_Init_ex(&hmac, key, md_size, md_type, NULL)
-        || !HMAC_Update(&hmac, p12->authsafes->d.data->data,
+    hmac = HMAC_CTX_new();
+    if (!HMAC_Init_ex(hmac, key, md_size, md_type, NULL)
+        || !HMAC_Update(hmac, p12->authsafes->d.data->data,
                         p12->authsafes->d.data->length)
-        || !HMAC_Final(&hmac, mac, maclen)) {
-        HMAC_CTX_cleanup(&hmac);
+        || !HMAC_Final(hmac, mac, maclen)) {
+        HMAC_CTX_free(hmac);
         return 0;
     }
-    HMAC_CTX_cleanup(&hmac);
+    HMAC_CTX_free(hmac);
     return 1;
 }
 
diff --git a/crypto/pkcs7/pk7_doit.c b/crypto/pkcs7/pk7_doit.c
index df83294..91864dc 100644
--- a/crypto/pkcs7/pk7_doit.c
+++ b/crypto/pkcs7/pk7_doit.c
@@ -692,7 +692,7 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
     int i, j;
     BIO *btmp;
     PKCS7_SIGNER_INFO *si;
-    EVP_MD_CTX *mdc, ctx_tmp;
+    EVP_MD_CTX *mdc, *ctx_tmp;
     STACK_OF(X509_ATTRIBUTE) *sk;
     STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL;
     ASN1_OCTET_STRING *os = NULL;
@@ -707,7 +707,12 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
         return 0;
     }
 
-    EVP_MD_CTX_init(&ctx_tmp);
+    ctx_tmp = EVP_MD_CTX_new();
+    if (ctx_tmp == NULL) {
+        PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
     i = OBJ_obj2nid(p7->type);
     p7->state = PKCS7_S_HEADER;
 
@@ -784,7 +789,7 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
             /*
              * We now have the EVP_MD_CTX, lets do the signing.
              */
-            if (!EVP_MD_CTX_copy_ex(&ctx_tmp, mdc))
+            if (!EVP_MD_CTX_copy_ex(ctx_tmp, mdc))
                 goto err;
 
             sk = si->auth_attr;
@@ -794,7 +799,7 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
              * sign the attributes
              */
             if (sk_X509_ATTRIBUTE_num(sk) > 0) {
-                if (!do_pkcs7_signed_attrib(si, &ctx_tmp))
+                if (!do_pkcs7_signed_attrib(si, ctx_tmp))
                     goto err;
             } else {
                 unsigned char *abuf = NULL;
@@ -804,7 +809,7 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
                 if (abuf == NULL)
                     goto err;
 
-                if (!EVP_SignFinal(&ctx_tmp, abuf, &abuflen, si->pkey)) {
+                if (!EVP_SignFinal(ctx_tmp, abuf, &abuflen, si->pkey)) {
                     PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_EVP_LIB);
                     goto err;
                 }
@@ -849,13 +854,13 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
     }
     ret = 1;
  err:
-    EVP_MD_CTX_cleanup(&ctx_tmp);
+    EVP_MD_CTX_free(ctx_tmp);
     return (ret);
 }
 
 int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si)
 {
-    EVP_MD_CTX mctx;
+    EVP_MD_CTX *mctx;
     EVP_PKEY_CTX *pctx;
     unsigned char *abuf = NULL;
     int alen;
@@ -866,8 +871,13 @@ int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si)
     if (md == NULL)
         return 0;
 
-    EVP_MD_CTX_init(&mctx);
-    if (EVP_DigestSignInit(&mctx, &pctx, md, NULL, si->pkey) <= 0)
+    mctx = EVP_MD_CTX_new();
+    if (mctx == NULL) {
+        PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    if (EVP_DigestSignInit(mctx, &pctx, md, NULL, si->pkey) <= 0)
         goto err;
 
     if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
@@ -880,16 +890,16 @@ int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si)
                          ASN1_ITEM_rptr(PKCS7_ATTR_SIGN));
     if (!abuf)
         goto err;
-    if (EVP_DigestSignUpdate(&mctx, abuf, alen) <= 0)
+    if (EVP_DigestSignUpdate(mctx, abuf, alen) <= 0)
         goto err;
     OPENSSL_free(abuf);
     abuf = NULL;
-    if (EVP_DigestSignFinal(&mctx, NULL, &siglen) <= 0)
+    if (EVP_DigestSignFinal(mctx, NULL, &siglen) <= 0)
         goto err;
     abuf = OPENSSL_malloc(siglen);
     if (abuf == NULL)
         goto err;
-    if (EVP_DigestSignFinal(&mctx, abuf, &siglen) <= 0)
+    if (EVP_DigestSignFinal(mctx, abuf, &siglen) <= 0)
         goto err;
 
     if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
@@ -898,7 +908,7 @@ int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si)
         goto err;
     }
 
-    EVP_MD_CTX_cleanup(&mctx);
+    EVP_MD_CTX_free(mctx);
 
     ASN1_STRING_set0(si->enc_digest, abuf, siglen);
 
@@ -906,7 +916,7 @@ int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si)
 
  err:
     OPENSSL_free(abuf);
-    EVP_MD_CTX_cleanup(&mctx);
+    EVP_MD_CTX_free(mctx);
     return 0;
 
 }
@@ -972,14 +982,18 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
                           X509 *x509)
 {
     ASN1_OCTET_STRING *os;
-    EVP_MD_CTX mdc_tmp, *mdc;
+    EVP_MD_CTX *mdc_tmp, *mdc;
     int ret = 0, i;
     int md_type;
     STACK_OF(X509_ATTRIBUTE) *sk;
     BIO *btmp;
     EVP_PKEY *pkey;
 
-    EVP_MD_CTX_init(&mdc_tmp);
+    mdc_tmp = EVP_MD_CTX_new();
+    if (mdc_tmp == NULL) {
+        PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
 
     if (!PKCS7_type_is_signed(p7) && !PKCS7_type_is_signedAndEnveloped(p7)) {
         PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_WRONG_PKCS7_TYPE);
@@ -1016,7 +1030,7 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
      * mdc is the digest ctx that we want, unless there are attributes, in
      * which case the digest is the signed attributes
      */
-    if (!EVP_MD_CTX_copy_ex(&mdc_tmp, mdc))
+    if (!EVP_MD_CTX_copy_ex(mdc_tmp, mdc))
         goto err;
 
     sk = si->auth_attr;
@@ -1026,7 +1040,7 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
         int alen;
         ASN1_OCTET_STRING *message_digest;
 
-        if (!EVP_DigestFinal_ex(&mdc_tmp, md_dat, &md_len))
+        if (!EVP_DigestFinal_ex(mdc_tmp, md_dat, &md_len))
             goto err;
         message_digest = PKCS7_digest_from_attributes(sk);
         if (!message_digest) {
@@ -1041,7 +1055,7 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
             goto err;
         }
 
-        if (!EVP_VerifyInit_ex(&mdc_tmp, EVP_get_digestbynid(md_type), NULL))
+        if (!EVP_VerifyInit_ex(mdc_tmp, EVP_get_digestbynid(md_type), NULL))
             goto err;
 
         alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf,
@@ -1051,7 +1065,7 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
             ret = -1;
             goto err;
         }
-        if (!EVP_VerifyUpdate(&mdc_tmp, abuf, alen))
+        if (!EVP_VerifyUpdate(mdc_tmp, abuf, alen))
             goto err;
 
         OPENSSL_free(abuf);
@@ -1064,7 +1078,7 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
         goto err;
     }
 
-    i = EVP_VerifyFinal(&mdc_tmp, os->data, os->length, pkey);
+    i = EVP_VerifyFinal(mdc_tmp, os->data, os->length, pkey);
     EVP_PKEY_free(pkey);
     if (i <= 0) {
         PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_SIGNATURE_FAILURE);
@@ -1073,7 +1087,7 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
     }
     ret = 1;
  err:
-    EVP_MD_CTX_cleanup(&mdc_tmp);
+    EVP_MD_CTX_free(mdc_tmp);
     return (ret);
 }
 
diff --git a/crypto/rand/md_rand.c b/crypto/rand/md_rand.c
index 698a638..c2dfce4 100644
--- a/crypto/rand/md_rand.c
+++ b/crypto/rand/md_rand.c
@@ -212,7 +212,7 @@ static int rand_add(const void *buf, int num, double add)
     int i, j, k, st_idx;
     long md_c[2];
     unsigned char local_md[MD_DIGEST_LENGTH];
-    EVP_MD_CTX m;
+    EVP_MD_CTX *m;
     int do_not_lock;
     int rv = 0;
 
@@ -234,7 +234,10 @@ static int rand_add(const void *buf, int num, double add)
      * hash function.
      */
 
-    EVP_MD_CTX_init(&m);
+    m = EVP_MD_CTX_new();
+    if (m == NULL)
+        goto err;
+
     /* check if we already have the lock */
     if (crypto_lock_rand) {
         CRYPTO_THREADID cur;
@@ -284,21 +287,21 @@ static int rand_add(const void *buf, int num, double add)
         j = (num - i);
         j = (j > MD_DIGEST_LENGTH) ? MD_DIGEST_LENGTH : j;
 
-        if (!MD_Init(&m))
+        if (!MD_Init(m))
             goto err;
-        if (!MD_Update(&m, local_md, MD_DIGEST_LENGTH))
+        if (!MD_Update(m, local_md, MD_DIGEST_LENGTH))
             goto err;
         k = (st_idx + j) - STATE_SIZE;
         if (k > 0) {
-            if (!MD_Update(&m, &(state[st_idx]), j - k))
+            if (!MD_Update(m, &(state[st_idx]), j - k))
                 goto err;
-            if (!MD_Update(&m, &(state[0]), k))
+            if (!MD_Update(m, &(state[0]), k))
                 goto err;
-        } else if (!MD_Update(&m, &(state[st_idx]), j))
+        } else if (!MD_Update(m, &(state[st_idx]), j))
             goto err;
 
         /* DO NOT REMOVE THE FOLLOWING CALL TO MD_Update()! */
-        if (!MD_Update(&m, buf, j))
+        if (!MD_Update(m, buf, j))
             goto err;
         /*
          * We know that line may cause programs such as purify and valgrind
@@ -308,9 +311,9 @@ static int rand_add(const void *buf, int num, double add)
          * insecure keys.
          */
 
-        if (!MD_Update(&m, (unsigned char *)&(md_c[0]), sizeof(md_c)))
+        if (!MD_Update(m, (unsigned char *)&(md_c[0]), sizeof(md_c)))
             goto err;
-        if (!MD_Final(&m, local_md))
+        if (!MD_Final(m, local_md))
             goto err;
         md_c[1]++;
 
@@ -352,7 +355,7 @@ static int rand_add(const void *buf, int num, double add)
 #endif
     rv = 1;
  err:
-    EVP_MD_CTX_cleanup(&m);
+    EVP_MD_CTX_free(m);
     return rv;
 }
 
@@ -369,7 +372,7 @@ static int rand_bytes(unsigned char *buf, int num, int pseudo)
     int ok;
     long md_c[2];
     unsigned char local_md[MD_DIGEST_LENGTH];
-    EVP_MD_CTX m;
+    EVP_MD_CTX *m;
 #ifndef GETPID_IS_MEANINGLESS
     pid_t curr_pid = getpid();
 #endif
@@ -409,7 +412,10 @@ static int rand_bytes(unsigned char *buf, int num, int pseudo)
     if (num <= 0)
         return 1;
 
-    EVP_MD_CTX_init(&m);
+    m = EVP_MD_CTX_new();
+    if (m == NULL)
+        goto err_mem;
+
     /* round upwards to multiple of MD_DIGEST_LENGTH/2 */
     num_ceil =
         (1 + (num - 1) / (MD_DIGEST_LENGTH / 2)) * (MD_DIGEST_LENGTH / 2);
@@ -523,26 +529,26 @@ static int rand_bytes(unsigned char *buf, int num, int pseudo)
         /* num_ceil -= MD_DIGEST_LENGTH/2 */
         j = (num >= MD_DIGEST_LENGTH / 2) ? MD_DIGEST_LENGTH / 2 : num;
         num -= j;
-        if (!MD_Init(&m))
+        if (!MD_Init(m))
             goto err;
 #ifndef GETPID_IS_MEANINGLESS
         if (curr_pid) {         /* just in the first iteration to save time */
-            if (!MD_Update(&m, (unsigned char *)&curr_pid, sizeof curr_pid))
+            if (!MD_Update(m, (unsigned char *)&curr_pid, sizeof curr_pid))
                 goto err;
             curr_pid = 0;
         }
 #endif
         if (curr_time) {        /* just in the first iteration to save time */
-            if (!MD_Update(&m, (unsigned char *)&curr_time, sizeof curr_time))
+            if (!MD_Update(m, (unsigned char *)&curr_time, sizeof curr_time))
                 goto err;
-            if (!MD_Update(&m, (unsigned char *)&tv, sizeof tv))
+            if (!MD_Update(m, (unsigned char *)&tv, sizeof tv))
                 goto err;
             curr_time = 0;
-            rand_hw_seed(&m);
+            rand_hw_seed(m);
         }
-        if (!MD_Update(&m, local_md, MD_DIGEST_LENGTH))
+        if (!MD_Update(m, local_md, MD_DIGEST_LENGTH))
             goto err;
-        if (!MD_Update(&m, (unsigned char *)&(md_c[0]), sizeof(md_c)))
+        if (!MD_Update(m, (unsigned char *)&(md_c[0]), sizeof(md_c)))
             goto err;
 
 #ifndef PURIFY                  /* purify complains */
@@ -553,19 +559,19 @@ static int rand_bytes(unsigned char *buf, int num, int pseudo)
          * builds it is not used: the removal of such a small source of
          * entropy has negligible impact on security.
          */
-        if (!MD_Update(&m, buf, j))
+        if (!MD_Update(m, buf, j))
             goto err;
 #endif
 
         k = (st_idx + MD_DIGEST_LENGTH / 2) - st_num;
         if (k > 0) {
-            if (!MD_Update(&m, &(state[st_idx]), MD_DIGEST_LENGTH / 2 - k))
+            if (!MD_Update(m, &(state[st_idx]), MD_DIGEST_LENGTH / 2 - k))
                 goto err;
-            if (!MD_Update(&m, &(state[0]), k))
+            if (!MD_Update(m, &(state[0]), k))
                 goto err;
-        } else if (!MD_Update(&m, &(state[st_idx]), MD_DIGEST_LENGTH / 2))
+        } else if (!MD_Update(m, &(state[st_idx]), MD_DIGEST_LENGTH / 2))
             goto err;
-        if (!MD_Final(&m, local_md))
+        if (!MD_Final(m, local_md))
             goto err;
 
         for (i = 0; i < MD_DIGEST_LENGTH / 2; i++) {
@@ -578,23 +584,23 @@ static int rand_bytes(unsigned char *buf, int num, int pseudo)
         }
     }
 
-    if (!MD_Init(&m)
-        || !MD_Update(&m, (unsigned char *)&(md_c[0]), sizeof(md_c))
-        || !MD_Update(&m, local_md, MD_DIGEST_LENGTH))
+    if (!MD_Init(m)
+        || !MD_Update(m, (unsigned char *)&(md_c[0]), sizeof(md_c))
+        || !MD_Update(m, local_md, MD_DIGEST_LENGTH))
         goto err;
     CRYPTO_w_lock(CRYPTO_LOCK_RAND);
     /*
      * Prevent deadlocks if we end up in an async engine
      */
     ASYNC_block_pause();
-    if (!MD_Update(&m, md, MD_DIGEST_LENGTH) || !MD_Final(&m, md)) {
+    if (!MD_Update(m, md, MD_DIGEST_LENGTH) || !MD_Final(m, md)) {
         CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
         goto err;
     }
     ASYNC_unblock_pause();
     CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
 
-    EVP_MD_CTX_cleanup(&m);
+    EVP_MD_CTX_free(m);
     if (ok)
         return (1);
     else if (pseudo)
@@ -606,8 +612,12 @@ static int rand_bytes(unsigned char *buf, int num, int pseudo)
         return (0);
     }
  err:
-    EVP_MD_CTX_cleanup(&m);
     RANDerr(RAND_F_RAND_BYTES, ERR_R_EVP_LIB);
+    EVP_MD_CTX_free(m);
+    return 0;
+ err_mem:
+    RANDerr(RAND_F_RAND_BYTES, ERR_R_MALLOC_FAILURE);
+    EVP_MD_CTX_free(m);
     return 0;
 
 }
diff --git a/crypto/rsa/rsa_ameth.c b/crypto/rsa/rsa_ameth.c
index bae43f2..68b268e 100644
--- a/crypto/rsa/rsa_ameth.c
+++ b/crypto/rsa/rsa_ameth.c
@@ -729,7 +729,7 @@ static int rsa_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
                          ASN1_BIT_STRING *sig)
 {
     int pad_mode;
-    EVP_PKEY_CTX *pkctx = ctx->pctx;
+    EVP_PKEY_CTX *pkctx = EVP_MD_CTX_pkey_ctx(ctx);
     if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0)
         return 0;
     if (pad_mode == RSA_PKCS1_PADDING)
diff --git a/crypto/rsa/rsa_oaep.c b/crypto/rsa/rsa_oaep.c
index ff551f2..0ad1ef3 100644
--- a/crypto/rsa/rsa_oaep.c
+++ b/crypto/rsa/rsa_oaep.c
@@ -242,13 +242,14 @@ int PKCS1_MGF1(unsigned char *mask, long len,
 {
     long i, outlen = 0;
     unsigned char cnt[4];
-    EVP_MD_CTX c;
+    EVP_MD_CTX *c = EVP_MD_CTX_new();
     unsigned char md[EVP_MAX_MD_SIZE];
     int mdlen;
     int rv = -1;
 
-    EVP_MD_CTX_init(&c);
-    mdlen = M_EVP_MD_size(dgst);
+    if (c == NULL)
+        goto err;
+    mdlen = EVP_MD_size(dgst);
     if (mdlen < 0)
         goto err;
     for (i = 0; outlen < len; i++) {
@@ -256,16 +257,16 @@ int PKCS1_MGF1(unsigned char *mask, long len,
         cnt[1] = (unsigned char)((i >> 16) & 255);
         cnt[2] = (unsigned char)((i >> 8)) & 255;
         cnt[3] = (unsigned char)(i & 255);
-        if (!EVP_DigestInit_ex(&c, dgst, NULL)
-            || !EVP_DigestUpdate(&c, seed, seedlen)
-            || !EVP_DigestUpdate(&c, cnt, 4))
+        if (!EVP_DigestInit_ex(c, dgst, NULL)
+            || !EVP_DigestUpdate(c, seed, seedlen)
+            || !EVP_DigestUpdate(c, cnt, 4))
             goto err;
         if (outlen + mdlen <= len) {
-            if (!EVP_DigestFinal_ex(&c, mask + outlen, NULL))
+            if (!EVP_DigestFinal_ex(c, mask + outlen, NULL))
                 goto err;
             outlen += mdlen;
         } else {
-            if (!EVP_DigestFinal_ex(&c, md, NULL))
+            if (!EVP_DigestFinal_ex(c, md, NULL))
                 goto err;
             memcpy(mask + outlen, md, len - outlen);
             outlen = len;
@@ -273,6 +274,6 @@ int PKCS1_MGF1(unsigned char *mask, long len,
     }
     rv = 0;
  err:
-    EVP_MD_CTX_cleanup(&c);
+    EVP_MD_CTX_free(c);
     return rv;
 }
diff --git a/crypto/rsa/rsa_pss.c b/crypto/rsa/rsa_pss.c
index 95bf6b0..5f44dd3 100644
--- a/crypto/rsa/rsa_pss.c
+++ b/crypto/rsa/rsa_pss.c
@@ -88,14 +88,17 @@ int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash,
     int hLen, maskedDBLen, MSBits, emLen;
     const unsigned char *H;
     unsigned char *DB = NULL;
-    EVP_MD_CTX ctx;
+    EVP_MD_CTX *ctx = EVP_MD_CTX_new();
     unsigned char H_[EVP_MAX_MD_SIZE];
-    EVP_MD_CTX_init(&ctx);
+
+
+    if (ctx == NULL)
+        goto err;
 
     if (mgf1Hash == NULL)
         mgf1Hash = Hash;
 
-    hLen = M_EVP_MD_size(Hash);
+    hLen = EVP_MD_size(Hash);
     if (hLen < 0)
         goto err;
     /*-
@@ -153,15 +156,15 @@ int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash,
         RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED);
         goto err;
     }
-    if (!EVP_DigestInit_ex(&ctx, Hash, NULL)
-        || !EVP_DigestUpdate(&ctx, zeroes, sizeof zeroes)
-        || !EVP_DigestUpdate(&ctx, mHash, hLen))
+    if (!EVP_DigestInit_ex(ctx, Hash, NULL)
+        || !EVP_DigestUpdate(ctx, zeroes, sizeof zeroes)
+        || !EVP_DigestUpdate(ctx, mHash, hLen))
         goto err;
     if (maskedDBLen - i) {
-        if (!EVP_DigestUpdate(&ctx, DB + i, maskedDBLen - i))
+        if (!EVP_DigestUpdate(ctx, DB + i, maskedDBLen - i))
             goto err;
     }
-    if (!EVP_DigestFinal_ex(&ctx, H_, NULL))
+    if (!EVP_DigestFinal_ex(ctx, H_, NULL))
         goto err;
     if (memcmp(H_, H, hLen)) {
         RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_BAD_SIGNATURE);
@@ -171,7 +174,7 @@ int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash,
 
  err:
     OPENSSL_free(DB);
-    EVP_MD_CTX_cleanup(&ctx);
+    EVP_MD_CTX_free(ctx);
 
     return ret;
 
@@ -193,12 +196,12 @@ int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM,
     int ret = 0;
     int hLen, maskedDBLen, MSBits, emLen;
     unsigned char *H, *salt = NULL, *p;
-    EVP_MD_CTX ctx;
+    EVP_MD_CTX *ctx = NULL;
 
     if (mgf1Hash == NULL)
         mgf1Hash = Hash;
 
-    hLen = M_EVP_MD_size(Hash);
+    hLen = EVP_MD_size(Hash);
     if (hLen < 0)
         goto err;
     /*-
@@ -241,16 +244,17 @@ int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM,
     }
     maskedDBLen = emLen - hLen - 1;
     H = EM + maskedDBLen;
-    EVP_MD_CTX_init(&ctx);
-    if (!EVP_DigestInit_ex(&ctx, Hash, NULL)
-        || !EVP_DigestUpdate(&ctx, zeroes, sizeof zeroes)
-        || !EVP_DigestUpdate(&ctx, mHash, hLen))
+    ctx = EVP_MD_CTX_new();
+    if (ctx == NULL)
+        goto err;
+    if (!EVP_DigestInit_ex(ctx, Hash, NULL)
+        || !EVP_DigestUpdate(ctx, zeroes, sizeof zeroes)
+        || !EVP_DigestUpdate(ctx, mHash, hLen))
         goto err;
-    if (sLen && !EVP_DigestUpdate(&ctx, salt, sLen))
+    if (sLen && !EVP_DigestUpdate(ctx, salt, sLen))
         goto err;
-    if (!EVP_DigestFinal_ex(&ctx, H, NULL))
+    if (!EVP_DigestFinal_ex(ctx, H, NULL))
         goto err;
-    EVP_MD_CTX_cleanup(&ctx);
 
     /* Generate dbMask in place then perform XOR on it */
     if (PKCS1_MGF1(EM, maskedDBLen, H, hLen, mgf1Hash))
@@ -278,6 +282,7 @@ int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM,
     ret = 1;
 
  err:
+    EVP_MD_CTX_free(ctx);
     OPENSSL_free(salt);
 
     return ret;
diff --git a/crypto/srp/srp_lib.c b/crypto/srp/srp_lib.c
index 850ec2c..0a073b6 100644
--- a/crypto/srp/srp_lib.c
+++ b/crypto/srp/srp_lib.c
@@ -70,31 +70,36 @@ static BIGNUM *srp_Calc_k(BIGNUM *N, BIGNUM *g)
 
     unsigned char digest[SHA_DIGEST_LENGTH];
     unsigned char *tmp;
-    EVP_MD_CTX ctxt;
+    EVP_MD_CTX *ctxt = NULL;
     int longg;
     int longN = BN_num_bytes(N);
+    BIGNUM *res = NULL;
 
     if (BN_ucmp(g, N) >= 0)
         return NULL;
 
-    if ((tmp = OPENSSL_malloc(longN)) == NULL)
+    ctxt = EVP_MD_CTX_new();
+    if (ctxt == NULL)
         return NULL;
+    if ((tmp = OPENSSL_malloc(longN)) == NULL)
+        goto err;
     BN_bn2bin(N, tmp);
 
-    EVP_MD_CTX_init(&ctxt);
-    EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL);
-    EVP_DigestUpdate(&ctxt, tmp, longN);
+    EVP_DigestInit_ex(ctxt, EVP_sha1(), NULL);
+    EVP_DigestUpdate(ctxt, tmp, longN);
 
     memset(tmp, 0, longN);
     longg = BN_bn2bin(g, tmp);
     /* use the zeros behind to pad on left */
-    EVP_DigestUpdate(&ctxt, tmp + longg, longN - longg);
-    EVP_DigestUpdate(&ctxt, tmp, longg);
+    EVP_DigestUpdate(ctxt, tmp + longg, longN - longg);
+    EVP_DigestUpdate(ctxt, tmp, longg);
     OPENSSL_free(tmp);
 
-    EVP_DigestFinal_ex(&ctxt, digest, NULL);
-    EVP_MD_CTX_cleanup(&ctxt);
-    return BN_bin2bn(digest, sizeof(digest), NULL);
+    EVP_DigestFinal_ex(ctxt, digest, NULL);
+    res = BN_bin2bn(digest, sizeof(digest), NULL);
+ err:
+    EVP_MD_CTX_free(ctxt);
+    return res;
 }
 
 BIGNUM *SRP_Calc_u(BIGNUM *A, BIGNUM *B, BIGNUM *N)
@@ -104,7 +109,7 @@ BIGNUM *SRP_Calc_u(BIGNUM *A, BIGNUM *B, BIGNUM *N)
     BIGNUM *u;
     unsigned char cu[SHA_DIGEST_LENGTH];
     unsigned char *cAB;
-    EVP_MD_CTX ctxt;
+    EVP_MD_CTX *ctxt = NULL;
     int longN;
     if ((A == NULL) || (B == NULL) || (N == NULL))
         return NULL;
@@ -114,25 +119,30 @@ BIGNUM *SRP_Calc_u(BIGNUM *A, BIGNUM *B, BIGNUM *N)
 
     longN = BN_num_bytes(N);
 
-    if ((cAB = OPENSSL_malloc(2 * longN)) == NULL)
+    ctxt = EVP_MD_CTX_new();
+    if (ctxt == NULL)
         return NULL;
+    if ((cAB = OPENSSL_malloc(2 * longN)) == NULL)
+        goto err;
 
     memset(cAB, 0, longN);
 
-    EVP_MD_CTX_init(&ctxt);
-    EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL);
-    EVP_DigestUpdate(&ctxt, cAB + BN_bn2bin(A, cAB + longN), longN);
-    EVP_DigestUpdate(&ctxt, cAB + BN_bn2bin(B, cAB + longN), longN);
+    EVP_DigestInit_ex(ctxt, EVP_sha1(), NULL);
+    EVP_DigestUpdate(ctxt, cAB + BN_bn2bin(A, cAB + longN), longN);
+    EVP_DigestUpdate(ctxt, cAB + BN_bn2bin(B, cAB + longN), longN);
     OPENSSL_free(cAB);
-    EVP_DigestFinal_ex(&ctxt, cu, NULL);
-    EVP_MD_CTX_cleanup(&ctxt);
+    EVP_DigestFinal_ex(ctxt, cu, NULL);
 
     if ((u = BN_bin2bn(cu, sizeof(cu), NULL)) == NULL)
-        return NULL;
-    if (!BN_is_zero(u))
-        return u;
-    BN_free(u);
-    return NULL;
+        goto err;
+    if (BN_is_zero(u)) {
+        BN_free(u);
+        u = NULL;
+    }
+ err:
+    EVP_MD_CTX_free(ctxt);
+
+    return u;
 }
 
 BIGNUM *SRP_Calc_server_key(BIGNUM *A, BIGNUM *v, BIGNUM *u, BIGNUM *b,
@@ -196,31 +206,36 @@ BIGNUM *SRP_Calc_B(BIGNUM *b, BIGNUM *N, BIGNUM *g, BIGNUM *v)
 BIGNUM *SRP_Calc_x(BIGNUM *s, const char *user, const char *pass)
 {
     unsigned char dig[SHA_DIGEST_LENGTH];
-    EVP_MD_CTX ctxt;
+    EVP_MD_CTX *ctxt;
     unsigned char *cs;
+    BIGNUM *res = NULL;
 
     if ((s == NULL) || (user == NULL) || (pass == NULL))
         return NULL;
 
-    if ((cs = OPENSSL_malloc(BN_num_bytes(s))) == NULL)
+    ctxt = EVP_MD_CTX_new();
+    if (ctxt == NULL)
         return NULL;
+    if ((cs = OPENSSL_malloc(BN_num_bytes(s))) == NULL)
+        goto err;
 
-    EVP_MD_CTX_init(&ctxt);
-    EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL);
-    EVP_DigestUpdate(&ctxt, user, strlen(user));
-    EVP_DigestUpdate(&ctxt, ":", 1);
-    EVP_DigestUpdate(&ctxt, pass, strlen(pass));
-    EVP_DigestFinal_ex(&ctxt, dig, NULL);
+    EVP_DigestInit_ex(ctxt, EVP_sha1(), NULL);
+    EVP_DigestUpdate(ctxt, user, strlen(user));
+    EVP_DigestUpdate(ctxt, ":", 1);
+    EVP_DigestUpdate(ctxt, pass, strlen(pass));
+    EVP_DigestFinal_ex(ctxt, dig, NULL);
 
-    EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL);
+    EVP_DigestInit_ex(ctxt, EVP_sha1(), NULL);
     BN_bn2bin(s, cs);
-    EVP_DigestUpdate(&ctxt, cs, BN_num_bytes(s));
+    EVP_DigestUpdate(ctxt, cs, BN_num_bytes(s));
     OPENSSL_free(cs);
-    EVP_DigestUpdate(&ctxt, dig, sizeof(dig));
-    EVP_DigestFinal_ex(&ctxt, dig, NULL);
-    EVP_MD_CTX_cleanup(&ctxt);
+    EVP_DigestUpdate(ctxt, dig, sizeof(dig));
+    EVP_DigestFinal_ex(ctxt, dig, NULL);
 
-    return BN_bin2bn(dig, sizeof(dig), NULL);
+    res = BN_bin2bn(dig, sizeof(dig), NULL);
+ err:
+    EVP_MD_CTX_free(ctxt);
+    return res;
 }
 
 BIGNUM *SRP_Calc_A(BIGNUM *a, BIGNUM *N, BIGNUM *g)
diff --git a/crypto/srp/srp_vfy.c b/crypto/srp/srp_vfy.c
index b271c99..1be68f2 100644
--- a/crypto/srp/srp_vfy.c
+++ b/crypto/srp/srp_vfy.c
@@ -474,7 +474,7 @@ SRP_user_pwd *SRP_VBASE_get_by_user(SRP_VBASE *vb, char *username)
     SRP_user_pwd *user;
     unsigned char digv[SHA_DIGEST_LENGTH];
     unsigned char digs[SHA_DIGEST_LENGTH];
-    EVP_MD_CTX ctxt;
+    EVP_MD_CTX *ctxt = NULL;
 
     if (vb == NULL)
         return NULL;
@@ -499,18 +499,20 @@ SRP_user_pwd *SRP_VBASE_get_by_user(SRP_VBASE *vb, char *username)
 
     if (RAND_bytes(digv, SHA_DIGEST_LENGTH) <= 0)
         goto err;
-    EVP_MD_CTX_init(&ctxt);
-    EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL);
-    EVP_DigestUpdate(&ctxt, vb->seed_key, strlen(vb->seed_key));
-    EVP_DigestUpdate(&ctxt, username, strlen(username));
-    EVP_DigestFinal_ex(&ctxt, digs, NULL);
-    EVP_MD_CTX_cleanup(&ctxt);
-    if (SRP_user_pwd_set_sv_BN
-        (user, BN_bin2bn(digs, SHA_DIGEST_LENGTH, NULL),
-         BN_bin2bn(digv, SHA_DIGEST_LENGTH, NULL)))
+    ctxt = EVP_MD_CTX_new();
+    EVP_DigestInit_ex(ctxt, EVP_sha1(), NULL);
+    EVP_DigestUpdate(ctxt, vb->seed_key, strlen(vb->seed_key));
+    EVP_DigestUpdate(ctxt, username, strlen(username));
+    EVP_DigestFinal_ex(ctxt, digs, NULL);
+    EVP_MD_CTX_free(ctxt);
+    ctxt = NULL;
+    if (SRP_user_pwd_set_sv_BN(user,
+                               BN_bin2bn(digs, SHA_DIGEST_LENGTH, NULL),
+                               BN_bin2bn(digv, SHA_DIGEST_LENGTH, NULL)))
         return user;
 
  err:
+    EVP_MD_CTX_free(ctxt);
     SRP_user_pwd_free(user);
     return NULL;
 }
diff --git a/crypto/ts/ts_rsp_verify.c b/crypto/ts/ts_rsp_verify.c
index 5a69a94..c79db38 100644
--- a/crypto/ts/ts_rsp_verify.c
+++ b/crypto/ts/ts_rsp_verify.c
@@ -529,7 +529,7 @@ static int ts_compute_imprint(BIO *data, TS_TST_INFO *tst_info,
     TS_MSG_IMPRINT *msg_imprint = tst_info->msg_imprint;
     X509_ALGOR *md_alg_resp = msg_imprint->hash_algo;
     const EVP_MD *md;
-    EVP_MD_CTX md_ctx;
+    EVP_MD_CTX *md_ctx = NULL;
     unsigned char buffer[4096];
     int length;
 
@@ -551,17 +551,24 @@ static int ts_compute_imprint(BIO *data, TS_TST_INFO *tst_info,
         goto err;
     }
 
-    if (!EVP_DigestInit(&md_ctx, md))
+    md_ctx = EVP_MD_CTX_new();
+    if (md_ctx == NULL) {
+        TSerr(TS_F_TS_COMPUTE_IMPRINT, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    if (!EVP_DigestInit(md_ctx, md))
         goto err;
     while ((length = BIO_read(data, buffer, sizeof(buffer))) > 0) {
-        if (!EVP_DigestUpdate(&md_ctx, buffer, length))
+        if (!EVP_DigestUpdate(md_ctx, buffer, length))
             goto err;
     }
-    if (!EVP_DigestFinal(&md_ctx, *imprint, NULL))
+    if (!EVP_DigestFinal(md_ctx, *imprint, NULL))
         goto err;
+    EVP_MD_CTX_free(md_ctx);
 
     return 1;
  err:
+    EVP_MD_CTX_free(md_ctx);
     X509_ALGOR_free(*md_alg);
     OPENSSL_free(*imprint);
     *imprint_len = 0;
diff --git a/crypto/x509/x509_cmp.c b/crypto/x509/x509_cmp.c
index 4017545..5c3ac6a 100644
--- a/crypto/x509/x509_cmp.c
+++ b/crypto/x509/x509_cmp.c
@@ -82,28 +82,29 @@ int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b)
 unsigned long X509_issuer_and_serial_hash(X509 *a)
 {
     unsigned long ret = 0;
-    EVP_MD_CTX ctx;
+    EVP_MD_CTX *ctx = EVP_MD_CTX_new();
     unsigned char md[16];
     char *f;
 
-    EVP_MD_CTX_init(&ctx);
+    if (ctx == NULL)
+        goto err;
     f = X509_NAME_oneline(a->cert_info.issuer, NULL, 0);
-    if (!EVP_DigestInit_ex(&ctx, EVP_md5(), NULL))
+    if (!EVP_DigestInit_ex(ctx, EVP_md5(), NULL))
         goto err;
-    if (!EVP_DigestUpdate(&ctx, (unsigned char *)f, strlen(f)))
+    if (!EVP_DigestUpdate(ctx, (unsigned char *)f, strlen(f)))
         goto err;
     OPENSSL_free(f);
     if (!EVP_DigestUpdate
-        (&ctx, (unsigned char *)a->cert_info.serialNumber.data,
+        (ctx, (unsigned char *)a->cert_info.serialNumber.data,
          (unsigned long)a->cert_info.serialNumber.length))
         goto err;
-    if (!EVP_DigestFinal_ex(&ctx, &(md[0]), NULL))
+    if (!EVP_DigestFinal_ex(ctx, &(md[0]), NULL))
         goto err;
     ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) |
            ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L)
         ) & 0xffffffffL;
  err:
-    EVP_MD_CTX_cleanup(&ctx);
+    EVP_MD_CTX_free(ctx);
     return (ret);
 }
 #endif
@@ -248,21 +249,23 @@ unsigned long X509_NAME_hash(X509_NAME *x)
 
 unsigned long X509_NAME_hash_old(X509_NAME *x)
 {
-    EVP_MD_CTX md_ctx;
+    EVP_MD_CTX *md_ctx = EVP_MD_CTX_new();
     unsigned long ret = 0;
     unsigned char md[16];
 
+    if (md_ctx == NULL)
+        return ret;
+
     /* Make sure X509_NAME structure contains valid cached encoding */
     i2d_X509_NAME(x, NULL);
-    EVP_MD_CTX_init(&md_ctx);
-    EVP_MD_CTX_set_flags(&md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
-    if (EVP_DigestInit_ex(&md_ctx, EVP_md5(), NULL)
-        && EVP_DigestUpdate(&md_ctx, x->bytes->data, x->bytes->length)
-        && EVP_DigestFinal_ex(&md_ctx, md, NULL))
+    EVP_MD_CTX_set_flags(md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
+    if (EVP_DigestInit_ex(md_ctx, EVP_md5(), NULL)
+        && EVP_DigestUpdate(md_ctx, x->bytes->data, x->bytes->length)
+        && EVP_DigestFinal_ex(md_ctx, md, NULL))
         ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) |
                ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L)
             ) & 0xffffffffL;
-    EVP_MD_CTX_cleanup(&md_ctx);
+    EVP_MD_CTX_free(md_ctx);
 
     return (ret);
 }
diff --git a/doc/crypto/EVP_DigestInit.pod b/doc/crypto/EVP_DigestInit.pod
index cfb9e14..1b98c1c 100644
--- a/doc/crypto/EVP_DigestInit.pod
+++ b/doc/crypto/EVP_DigestInit.pod
@@ -2,9 +2,9 @@
 
 =head1 NAME
 
-EVP_MD_CTX_init, EVP_MD_CTX_create, EVP_DigestInit_ex, EVP_DigestUpdate,
-EVP_DigestFinal_ex, EVP_MD_CTX_cleanup, EVP_MD_CTX_destroy, EVP_MAX_MD_SIZE,
-EVP_MD_CTX_copy_ex, EVP_DigestInit, EVP_DigestFinal, EVP_MD_CTX_copy, EVP_MD_type,
+EVP_MD_CTX_new, EVP_MD_CTX_reset, EVP_MD_CTX_free, EVP_MD_CTX_copy_ex,
+EVP_DigestInit_ex, EVP_DigestUpdate, EVP_DigestFinal_ex, EVP_MAX_MD_SIZE,
+EVP_DigestInit, EVP_DigestFinal, EVP_MD_CTX_copy, EVP_MD_type,
 EVP_MD_pkey_type, EVP_MD_size, EVP_MD_block_size, EVP_MD_CTX_md, EVP_MD_CTX_size,
 EVP_MD_CTX_block_size, EVP_MD_CTX_type, EVP_md_null, EVP_md2, EVP_md5, EVP_sha1,
 EVP_sha224, EVP_sha256, EVP_sha384, EVP_sha512, EVP_mdc2,
@@ -15,17 +15,15 @@ EVP digest routines
 
  #include <openssl/evp.h>
 
- void EVP_MD_CTX_init(EVP_MD_CTX *ctx);
- EVP_MD_CTX *EVP_MD_CTX_create(void);
+ EVP_MD_CTX *EVP_MD_CTX_new(void);
+ int EVP_MD_CTX_reset(EVP_MD_CTX *ctx);
+ void EVP_MD_CTX_free(EVP_MD_CTX *ctx);
 
  int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl);
  int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d, size_t cnt);
  int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md,
         unsigned int *s);
 
- int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx);
- void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx);
-
  int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out,const EVP_MD_CTX *in);
 
  int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type);
@@ -42,9 +40,16 @@ EVP digest routines
  int EVP_MD_block_size(const EVP_MD *md);
 
  const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx);
- #define EVP_MD_CTX_size(e)		EVP_MD_size(EVP_MD_CTX_md(e))
- #define EVP_MD_CTX_block_size(e)	EVP_MD_block_size((e)->digest)
- #define EVP_MD_CTX_type(e)		EVP_MD_type((e)->digest)
+ int (*EVP_MD_CTX_update_fn(EVP_MD_CTX *ctx))(EVP_MD_CTX *ctx,
+                                              const void *data, size_t count);
+ void EVP_MD_CTX_set_update_fn(EVP_MD_CTX *ctx,
+                               int (*update) (EVP_MD_CTX *ctx,
+                                              const void *data, size_t count));
+ int EVP_MD_CTX_size(const EVP_MD *ctx);
+ int EVP_MD_CTX_block_size(const EVP_MD *ctx);
+ int EVP_MD_CTX_type(const EVP_MD *ctx);
+ EVP_PKEY_CTX *EVP_MD_CTX_pkey_ctx(const EVP_MD_CTX *ctx);
+ void *EVP_MD_CTX_md_data(const EVP_MD_CTX *ctx);
 
  const EVP_MD *EVP_md_null(void);
  const EVP_MD *EVP_md2(void);
@@ -59,17 +64,21 @@ EVP digest routines
  const EVP_MD *EVP_sha512(void);
 
  const EVP_MD *EVP_get_digestbyname(const char *name);
- #define EVP_get_digestbynid(a) EVP_get_digestbyname(OBJ_nid2sn(a))
- #define EVP_get_digestbyobj(a) EVP_get_digestbynid(OBJ_obj2nid(a))
+ const EVP_MD *EVP_get_digestbynid(int type);
+ const EVP_MD *EVP_get_digestbyobj(const ASN1_OBJECT *o);
 
 =head1 DESCRIPTION
 
 The EVP digest routines are a high level interface to message digests,
 and should be used instead of the cipher-specific functions.
 
-EVP_MD_CTX_init() initializes digest context B<ctx>.
+EVP_MD_CTX_new() allocates, initializes and returns a digest context.
+
+EVP_MD_CTX_reset() resets the digest context B<ctx>.  This can be used
+to reuse an already existing context.
 
-EVP_MD_CTX_create() allocates, initializes and returns a digest context.
+EVP_MD_CTX_free() cleans up digest context B<ctx> and frees up the
+space allocated to it.
 
 EVP_DigestInit_ex() sets up digest context B<ctx> to use a digest
 B<type> from ENGINE B<impl>. B<ctx> must be initialized before calling this
@@ -88,13 +97,6 @@ After calling EVP_DigestFinal_ex() no additional calls to EVP_DigestUpdate()
 can be made, but EVP_DigestInit_ex() can be called to initialize a new
 digest operation.
 
-EVP_MD_CTX_cleanup() cleans up digest context B<ctx>, it should be called
-after a digest context is no longer needed.
-
-EVP_MD_CTX_destroy() cleans up digest context B<ctx> and frees up the
-space allocated to it, it should be called only on a context created
-using EVP_MD_CTX_create().
-
 EVP_MD_CTX_copy_ex() can be used to copy the message digest state from
 B<in> to B<out>. This is useful if large amounts of data are to be
 hashed which only differ in the last few bytes. B<out> must be initialized
@@ -186,17 +188,9 @@ implementations of digests to be specified.
 If digest contexts are not cleaned up after use
 memory leaks will occur.
 
-Stack allocation of EVP_MD_CTX structures is common, for example:
-
- EVP_MD_CTX mctx;
- EVP_MD_CTX_init(&mctx);
-
-This will cause binary compatibility issues if the size of EVP_MD_CTX
-structure changes (this will only happen with a major release of OpenSSL).
-Applications wishing to avoid this should use EVP_MD_CTX_create() instead:
-
- EVP_MD_CTX *mctx;
- mctx = EVP_MD_CTX_create();
+EVP_MD_CTX_size(), EVP_MD_CTX_block_size(), EVP_MD_CTX_type(),
+EVP_get_digestbynid() and EVP_get_digestbyobj() are defined as
+macros.
 
 
 =head1 EXAMPLE
@@ -230,12 +224,12 @@ digest name passed on the command line.
 	exit(1);
  }
 
- mdctx = EVP_MD_CTX_create();
+ mdctx = EVP_MD_CTX_new();
  EVP_DigestInit_ex(mdctx, md, NULL);
  EVP_DigestUpdate(mdctx, mess1, strlen(mess1));
  EVP_DigestUpdate(mdctx, mess2, strlen(mess2));
  EVP_DigestFinal_ex(mdctx, md_value, &md_len);
- EVP_MD_CTX_destroy(mdctx);
+ EVP_MD_CTX_free(mdctx);
 
  printf("Digest is: ");
  for(i = 0; i < md_len; i++)
@@ -254,6 +248,12 @@ L<evp(3)>
 
 =head1 HISTORY
 
+B<EVP_MD_CTX> became opaque in OpenSSL 1.1.  Consequently, stack
+allocated B<EVP_MD_CTX>s are no longer supported.
+
+EVP_MD_CTX_create() and EVP_MD_CTX_destroy() were renamed to
+EVP_MD_CTX_new() and EVP_MD_CTX_free() in OpenSSL 1.1.
+
 The link between digests and signing algorithms was fixed in OpenSSL 1.0 and
 later, so now EVP_sha1() can be used with RSA and DSA. The legacy EVP_dss1()
 was removed in OpenSSL 1.1.0
diff --git a/doc/crypto/EVP_DigestSignInit.pod b/doc/crypto/EVP_DigestSignInit.pod
index caad7fa..4b9eb21 100644
--- a/doc/crypto/EVP_DigestSignInit.pod
+++ b/doc/crypto/EVP_DigestSignInit.pod
@@ -18,8 +18,8 @@ EVP_DigestSignInit, EVP_DigestSignUpdate, EVP_DigestSignFinal - EVP signing func
 The EVP signature routines are a high level interface to digital signatures.
 
 EVP_DigestSignInit() sets up signing context B<ctx> to use digest B<type> from
-ENGINE B<impl> and private key B<pkey>. B<ctx> must be initialized with
-EVP_MD_CTX_init() before calling this function. If B<pctx> is not NULL the
+ENGINE B<impl> and private key B<pkey>. B<ctx> must be created with
+EVP_MD_CTX_new() before calling this function. If B<pctx> is not NULL the
 EVP_PKEY_CTX of the signing operation will be written to B<*pctx>: this can
 be used to set alternative signing options.
 
diff --git a/doc/crypto/EVP_DigestVerifyInit.pod b/doc/crypto/EVP_DigestVerifyInit.pod
index 338fc74..cc740b7 100644
--- a/doc/crypto/EVP_DigestVerifyInit.pod
+++ b/doc/crypto/EVP_DigestVerifyInit.pod
@@ -18,8 +18,8 @@ EVP_DigestVerifyInit, EVP_DigestVerifyUpdate, EVP_DigestVerifyFinal - EVP signat
 The EVP signature routines are a high level interface to digital signatures.
 
 EVP_DigestVerifyInit() sets up verification context B<ctx> to use digest
-B<type> from ENGINE B<impl> and public key B<pkey>. B<ctx> must be initialized
-with EVP_MD_CTX_init() before calling this function. If B<pctx> is not NULL the
+B<type> from ENGINE B<impl> and public key B<pkey>. B<ctx> must be created
+with EVP_MD_CTX_new() before calling this function. If B<pctx> is not NULL the
 EVP_PKEY_CTX of the verification operation will be written to B<*pctx>: this
 can be used to set alternative verification options.
 
diff --git a/doc/crypto/EVP_MD_meth_new.pod b/doc/crypto/EVP_MD_meth_new.pod
new file mode 100644
index 0000000..a6a17cd
--- /dev/null
+++ b/doc/crypto/EVP_MD_meth_new.pod
@@ -0,0 +1,160 @@
+=pod
+
+=head1 NAME
+
+EVP_MD_meth_new, EVP_MD_meth_free, EVP_MD_meth_set_input_blocksize,
+EVP_MD_meth_set_result_size, EVP_MD_meth_set_app_datasize,
+EVP_MD_meth_set_flags, EVP_MD_meth_set_init, EVP_MD_meth_set_update,
+EVP_MD_meth_set_final, EVP_MD_meth_set_copy, EVP_MD_meth_set_cleanup,
+EVP_MD_meth_set_ctrl, EVP_MD_meth_get_input_blocksize,
+EVP_MD_meth_get_result_size, EVP_MD_meth_get_app_datasize,
+EVP_MD_meth_get_flags, EVP_MD_meth_get_init, EVP_MD_meth_get_update,
+EVP_MD_meth_get_final, EVP_MD_meth_get_copy, EVP_MD_meth_get_cleanup,
+EVP_MD_meth_get_ctrl, EVP_MD_meth_get_pkey_types,
+EVP_MD_meth_get_sign, EVP_MD_meth_get_verify - Routines to build up
+EVP_MD methods
+
+=head1 SYNOPSIS
+
+ #include <openssl/evp.h>
+
+ EVP_MD *EVP_MD_create_method(int md_type, int pkey_type);
+ EVP_MD *EVP_MD_meth_dup(const EVP_MD *md);
+ void EVP_MD_destroy_method(EVP_MD *md);
+
+ int EVP_MD_meth_set_input_blocksize(EVP_MD *md, int blocksize);
+ int EVP_MD_meth_set_result_size(EVP_MD *md, int resultsize);
+ int EVP_MD_meth_set_app_datasize(EVP_MD *md, int datasize);
+ int EVP_MD_meth_set_flags(EVP_MD *md, unsigned long flags);
+ int EVP_MD_meth_set_init(EVP_MD *md, int (*init)(EVP_MD_CTX *ctx));
+ int EVP_MD_meth_set_update(EVP_MD *md, int (*update)(EVP_MD_CTX *ctx,
+                                                      const void *data,
+                                                      size_t count));
+ int EVP_MD_meth_set_final(EVP_MD *md, int (*final)(EVP_MD_CTX *ctx,
+                                                    unsigned char *md));
+ int EVP_MD_meth_set_copy(EVP_MD *md, int (*copy)(EVP_MD_CTX *to,
+                                                  const EVP_MD_CTX *from));
+ int EVP_MD_meth_set_cleanup(EVP_MD *md, int (*cleanup)(EVP_MD_CTX *ctx));
+ int EVP_MD_meth_set_ctrl(EVP_MD *md, int (*ctrl)(EVP_MD_CTX *ctx, int cmd,
+                                                  int p1, void *p2));
+
+ int EVP_MD_meth_get_input_blocksize(const EVP_MD *md);
+ int EVP_MD_meth_get_result_size(const EVP_MD *md);
+ int EVP_MD_meth_get_app_datasize(const EVP_MD *md);
+ unsigned long EVP_MD_meth_get_flags(const EVP_MD *md);
+ int (*EVP_MD_meth_get_init(const EVP_MD *md))(EVP_MD_CTX *ctx);
+ int (*EVP_MD_meth_get_update(const EVP_MD *md))(EVP_MD_CTX *ctx,
+                                                 const void *data,
+                                                 size_t count);
+ int (*EVP_MD_meth_get_final(const EVP_MD *md))(EVP_MD_CTX *ctx,
+                                                unsigned char *md);
+ int (*EVP_MD_meth_get_copy(const EVP_MD *md))(EVP_MD_CTX *to,
+                                               const EVP_MD_CTX *from);
+ int (*EVP_MD_meth_get_cleanup(const EVP_MD *md))(EVP_MD_CTX *ctx);
+ int (*EVP_MD_meth_get_ctrl(const EVP_MD *md))(EVP_MD_CTX *ctx, int cmd,
+                                               int p1, void *p2);
+
+=head1 DESCRIPTION
+
+The B<EVP_MD> type is a structure for digest method implementation.
+It can also have associated public/private key signing and verifying
+routines.
+
+EVP_MD_meth_new() creates a new B<EVP_MD> structure.
+
+EVP_MD_meth_dup() creates a copy of B<md>.
+
+EVP_MD_meth_free() destroys a B<EVP_MD> structure.
+
+EVP_MD_meth_set_input_blocksize() sets the internal input block size
+for the method B<md> to B<blocksize> bytes.
+
+EVP_MD_meth_set_result_size() sets the size of the result that the
+digest method in B<md> is expected to produce to B<resultsize> bytes.
+
+The digest method may have its own private data, which OpenSSL will
+allocate for it.  EVP_MD_meth_set_app_datasize() should be used to
+set the size for it to B<datasize>.
+
+EVP_MD_meth_set_flags() sets the flags to describe optional
+behaviours in the particular B<md>.  Several flags can be or'd
+together.  The available flags are:
+
+=over 4
+
+=item EVP_MD_FLAG_ONESHOT
+
+This digest method can only handles one block of input.
+
+=item EVP_MD_FLAG_DIGALGID_NULL
+
+When setting up a DigestAlgorithmIdentifier, this flag will have the
+parameter set to NULL by default.  Use this for PKCS#1.  I<Note: if
+combined with EVP_MD_FLAG_DIGALGID_ABSENT, the latter will override.>
+
+=item EVP_MD_FLAG_DIGALGID_ABSENT
+
+When setting up a DigestAlgorithmIdentifier, this flag will have the
+parameter be left absent by default.  I<Note: if combined with
+EVP_MD_FLAG_DIGALGID_NULL, the latter will be overriden.>
+
+=item EVP_MD_FLAG_DIGALGID_CUSTOM
+
+Custom DigestAlgorithmIdentifier handling via ctrl, with
+B<EVP_MD_FLAG_DIGALGID_ABSENT> as default.  I<Note: if combined with
+EVP_MD_FLAG_DIGALGID_NULL, the latter will be overriden.>
+Currently unused.
+
+=back
+
+EVP_MD_meth_set_init() sets the digest init function for B<md>.
+The digest init function is called by EVP_DigestInit(),
+EVP_DigestInit_ex(), EVP_SignInit, EVP_SignInit_ex(), EVP_VerifyInit()
+and EVP_VerifyInit_ex().
+
+EVP_MD_meth_set_update() sets the digest update function for B<md>.
+The digest update function is called by EVP_DigestUpdate(),
+EVP_SignUpdate().
+
+EVP_MD_meth_set_final() sets the digest final function for B<md>.
+The digest final function is called by EVP_DigestFinal(),
+EVP_DigestFinal_ex(), EVP_SignFinal() and EVP_VerifyFinal().
+
+EVP_MD_meth_set_copy() sets the function for B<md> to do extra
+computations after the method's private data structure has been copied
+from one B<EVP_MD_CTX> to another.  If all that's needed is to copy
+the data, there is no need for this copy function.
+Note that the copy function is passed two B<EVP_MD_CTX *>, the private
+data structure is then available with EVP_MD_CTX_md_data().
+This copy function is called by EVP_MD_CTX_copy() and
+EVP_MD_CTX_copy_ex().
+
+EVP_MD_meth_set_cleanup() sets the function for B<md> to do extra
+cleanup before the method's privata data structure is cleaned out and
+freed.
+Note that the cleanup function is passed a B<EVP_MD_CTX *>, the
+private data structure is then available with EVP_MD_CTX_md_data().
+This cleanup function is called by EVP_MD_CTX_reset() and
+EVP_MD_CTX_free().
+
+EVP_MD_meth_set_ctrl() sets the control function for B<md>.
+
+
+EVP_MD_meth_get_input_blocksize(), EVP_MD_meth_get_result_size(),
+EVP_MD_meth_get_app_datasize(), EVP_MD_meth_get_flags(),
+EVP_MD_meth_get_init(), EVP_MD_meth_get_update(),
+EVP_MD_meth_get_final(), EVP_MD_meth_get_copy(),
+EVP_MD_meth_get_cleanup() and EVP_MD_meth_get_ctrl() are all used
+to retrieve the method data given with the EVP_MD_meth_set_*()
+functions above.
+
+=head1 SEE ALSO
+
+L<EVP_DigestInit(3)>, L<EVP_SignInit(3)>, L<EVP_VerifyInit(3)>
+
+=head1 HISTORY
+
+The B<EVP_MD> structure was openly available in OpenSSL before version
+1.1.  The functions described here were added in OpenSSL version 1.1.
+
+=cut
diff --git a/doc/crypto/EVP_SignInit.pod b/doc/crypto/EVP_SignInit.pod
index afb2942..185b113 100644
--- a/doc/crypto/EVP_SignInit.pod
+++ b/doc/crypto/EVP_SignInit.pod
@@ -23,8 +23,8 @@ The EVP signature routines are a high level interface to digital
 signatures.
 
 EVP_SignInit_ex() sets up signing context B<ctx> to use digest
-B<type> from ENGINE B<impl>. B<ctx> must be initialized with
-EVP_MD_CTX_init() before calling this function.
+B<type> from ENGINE B<impl>. B<ctx> must be created with
+EVP_MD_CTX_new() before calling this function.
 
 EVP_SignUpdate() hashes B<cnt> bytes of data at B<d> into the
 signature context B<ctx>. This function can be called several times on the
diff --git a/doc/crypto/EVP_VerifyInit.pod b/doc/crypto/EVP_VerifyInit.pod
index 1a1d980..7fb6e63 100644
--- a/doc/crypto/EVP_VerifyInit.pod
+++ b/doc/crypto/EVP_VerifyInit.pod
@@ -20,8 +20,8 @@ The EVP signature verification routines are a high level interface to digital
 signatures.
 
 EVP_VerifyInit_ex() sets up verification context B<ctx> to use digest
-B<type> from ENGINE B<impl>. B<ctx> must be initialized by calling
-EVP_MD_CTX_init() before calling this function.
+B<type> from ENGINE B<impl>. B<ctx> must be created by calling
+EVP_MD_CTX_new() before calling this function.
 
 EVP_VerifyUpdate() hashes B<cnt> bytes of data at B<d> into the
 verification context B<ctx>. This function can be called several times on the
diff --git a/doc/crypto/hmac.pod b/doc/crypto/hmac.pod
index 753617a..d8e2498 100644
--- a/doc/crypto/hmac.pod
+++ b/doc/crypto/hmac.pod
@@ -2,7 +2,7 @@
 
 =head1 NAME
 
-HMAC, HMAC_CTX_init, HMAC_Init, HMAC_Init_ex, HMAC_Update, HMAC_Final, HMAC_CTX_cleanup - HMAC message authentication code
+HMAC, HMAC_CTX_new, HMAC_CTX_reset, HMAC_CTX_free, HMAC_Init, HMAC_Init_ex, HMAC_Update, HMAC_Final - HMAC message authentication code
 
 =head1 SYNOPSIS
 
@@ -12,7 +12,8 @@ HMAC, HMAC_CTX_init, HMAC_Init, HMAC_Init_ex, HMAC_Update, HMAC_Final, HMAC_CTX_
                int key_len, const unsigned char *d, int n,
                unsigned char *md, unsigned int *md_len);
 
- void HMAC_CTX_init(HMAC_CTX *ctx);
+ HMAC_CTX *HMAC_CTX_new(void);
+ int HMAC_CTX_reset(HMAC_CTX *ctx);
 
  int HMAC_Init(HMAC_CTX *ctx, const void *key, int key_len,
                const EVP_MD *md);
@@ -21,7 +22,7 @@ HMAC, HMAC_CTX_init, HMAC_Init, HMAC_Init_ex, HMAC_Update, HMAC_Final, HMAC_CTX_
  int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, int len);
  int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len);
 
- void HMAC_CTX_cleanup(HMAC_CTX *ctx);
+ void HMAC_CTX_free(HMAC_CTX *ctx);
 
 =head1 DESCRIPTION
 
@@ -40,12 +41,15 @@ the output is placed in B<md_len>, unless it is B<NULL>.
 
 B<evp_md> can be EVP_sha1(), EVP_ripemd160() etc.
 
-HMAC_CTX_init() initialises a B<HMAC_CTX> before first use. It must be
-called.
+HMAC_CTX_new() creates a new HMAC_CTX in heap memory.
 
-HMAC_CTX_cleanup() erases the key and other data from the B<HMAC_CTX>
-and releases any associated resources. It must be called when an
-B<HMAC_CTX> is no longer required.
+HMAC_CTX_reset() zeroes an existing B<HMAC_CTX> and associated
+resources, making it suitable for new computations as if it was newly
+created with HMAC_CTX_new().
+
+HMAC_CTX_free() erases the key and other data from the B<HMAC_CTX>,
+releases any associated resources and finally frees the B<HMAC_CTX>
+itself.
 
 The following functions may be used if the message is not completely
 stored in memory:
@@ -57,8 +61,8 @@ with OpenSSL 0.9.6b.
 
 HMAC_Init_ex() initializes or reuses a B<HMAC_CTX> structure to use
 the function B<evp_md> and key B<key>. Either can be NULL, in which
-case the existing one will be reused. HMAC_CTX_init() must have been
-called before the first use of an B<HMAC_CTX> in this
+case the existing one will be reused. B<ctx> must have been created
+with HMAC_CTX_new() before the first use of an B<HMAC_CTX> in this
 function. B<N.B. HMAC_Init() had this undocumented behaviour in
 previous versions of OpenSSL - failure to switch to HMAC_Init_ex() in
 programs that expect it will cause them to stop working>.
@@ -74,10 +78,13 @@ must have space for the hash function output.
 HMAC() returns a pointer to the message authentication code or NULL if
 an error occurred.
 
-HMAC_Init_ex(), HMAC_Update() and HMAC_Final() return 1 for success or 0 if
-an error occurred.
+HMAC_CTX_new() returns a pointer to a new B<HMAC_CTX> on success or
+B<NULL> if an error occurred.
+
+HMAC_CTX_reset(), HMAC_Init_ex(), HMAC_Update() and HMAC_Final() return 1
+for success or 0 if an error occurred.
 
-HMAC_CTX_init() and HMAC_CTX_cleanup() do not return values.
+HMAC_CTX_free() do not return values.
 
 =head1 CONFORMING TO
 
@@ -89,6 +96,12 @@ L<sha(3)>, L<evp(3)>
 
 =head1 HISTORY
 
+HMAC_CTX_init() was replaced with HMAC_CTX_reset() in OpenSSL versions 1.1.
+
+HMAC_CTX_cleanup() existed in OpenSSL versions before 1.1.
+
+HMAC_CTX_new() and HMAC_CTX_free() are new in OpenSSL version 1.1.
+
 HMAC_Init_ex(), HMAC_Update() and HMAC_Final() did not return values in
 versions of OpenSSL before 1.0.0.
 
diff --git a/engines/ccgost/gost_crypt.c b/engines/ccgost/gost_crypt.c
index fb066d9..062884f 100644
--- a/engines/ccgost/gost_crypt.c
+++ b/engines/ccgost/gost_crypt.c
@@ -85,20 +85,37 @@ static int gost_imit_cleanup(EVP_MD_CTX *ctx);
 /* Control function, knows how to set MAC key.*/
 static int gost_imit_ctrl(EVP_MD_CTX *ctx, int type, int arg, void *ptr);
 
-EVP_MD imit_gost_cpa = {
-    NID_id_Gost28147_89_MAC,
-    NID_undef,
-    4,
-    0,
-    gost_imit_init_cpa,
-    gost_imit_update,
-    gost_imit_final,
-    gost_imit_copy,
-    gost_imit_cleanup,
-    8,
-    sizeof(struct ossl_gost_imit_ctx),
-    gost_imit_ctrl
-};
+static EVP_MD *_hidden_Gost28147_89_MAC_md = NULL;
+EVP_MD *imit_gost_cpa(void)
+{
+
+    if (_hidden_Gost28147_89_MAC_md == NULL) {
+        EVP_MD *md;
+
+        if ((md = EVP_MD_meth_new(NID_id_Gost28147_89_MAC, NID_undef)) == NULL
+            || !EVP_MD_meth_set_result_size(md, 4)
+            || !EVP_MD_meth_set_input_blocksize(md, 8)
+            || !EVP_MD_meth_set_app_datasize(md,
+                                             sizeof(struct ossl_gost_imit_ctx))
+            || !EVP_MD_meth_set_flags(md, 0)
+            || !EVP_MD_meth_set_init(md, gost_imit_init_cpa)
+            || !EVP_MD_meth_set_update(md, gost_imit_update)
+            || !EVP_MD_meth_set_final(md, gost_imit_final)
+            || !EVP_MD_meth_set_copy(md, gost_imit_copy)
+            || !EVP_MD_meth_set_cleanup(md, gost_imit_cleanup)
+            || !EVP_MD_meth_set_ctrl(md, gost_imit_ctrl)) {
+            EVP_MD_meth_free(md);
+            md = NULL;
+        }
+        _hidden_Gost28147_89_MAC_md = md;
+    }
+    return _hidden_Gost28147_89_MAC_md;
+}
+void imit_gost_cpa_destroy(void)
+{
+    EVP_MD_meth_free(_hidden_Gost28147_89_MAC_md);
+    _hidden_Gost28147_89_MAC_md = NULL;
+}
 
 /*
  * Correspondence between gost parameter OIDs and substitution blocks
@@ -500,7 +517,7 @@ int gost89_get_asn1_parameters(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params)
 
 int gost_imit_init_cpa(EVP_MD_CTX *ctx)
 {
-    struct ossl_gost_imit_ctx *c = ctx->md_data;
+    struct ossl_gost_imit_ctx *c = EVP_MD_CTX_md_data(ctx);
     memset(c->buffer, 0, sizeof(c->buffer));
     memset(c->partial_block, 0, sizeof(c->partial_block));
     c->count = 0;
@@ -529,7 +546,7 @@ static void mac_block_mesh(struct ossl_gost_imit_ctx *c,
 
 int gost_imit_update(EVP_MD_CTX *ctx, const void *data, size_t count)
 {
-    struct ossl_gost_imit_ctx *c = ctx->md_data;
+    struct ossl_gost_imit_ctx *c = EVP_MD_CTX_md_data(ctx);
     const unsigned char *p = data;
     size_t bytes = count, i;
     if (!(c->key_set)) {
@@ -561,7 +578,7 @@ int gost_imit_update(EVP_MD_CTX *ctx, const void *data, size_t count)
 
 int gost_imit_final(EVP_MD_CTX *ctx, unsigned char *md)
 {
-    struct ossl_gost_imit_ctx *c = ctx->md_data;
+    struct ossl_gost_imit_ctx *c = EVP_MD_CTX_md_data(ctx);
     if (!c->key_set) {
         GOSTerr(GOST_F_GOST_IMIT_FINAL, GOST_R_MAC_KEY_NOT_SET);
         return 0;
@@ -595,9 +612,9 @@ int gost_imit_ctrl(EVP_MD_CTX *ctx, int type, int arg, void *ptr)
                 return 0;
             }
 
-            gost_key(&(((struct ossl_gost_imit_ctx *)(ctx->md_data))->cctx),
+            gost_key(&(((struct ossl_gost_imit_ctx *)(EVP_MD_CTX_md_data(ctx)))->cctx),
                      ptr);
-            ((struct ossl_gost_imit_ctx *)(ctx->md_data))->key_set = 1;
+            ((struct ossl_gost_imit_ctx *)(EVP_MD_CTX_md_data(ctx)))->key_set = 1;
             return 1;
 
         }
@@ -608,13 +625,14 @@ int gost_imit_ctrl(EVP_MD_CTX *ctx, int type, int arg, void *ptr)
 
 int gost_imit_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from)
 {
-    memcpy(to->md_data, from->md_data, sizeof(struct ossl_gost_imit_ctx));
+    memcpy(EVP_MD_CTX_md_data(to), EVP_MD_CTX_md_data(from),
+           sizeof(struct ossl_gost_imit_ctx));
     return 1;
 }
 
 /* Clean up imit ctx */
 int gost_imit_cleanup(EVP_MD_CTX *ctx)
 {
-    memset(ctx->md_data, 0, sizeof(struct ossl_gost_imit_ctx));
+    memset(EVP_MD_CTX_md_data(ctx), 0, sizeof(struct ossl_gost_imit_ctx));
     return 1;
 }
diff --git a/engines/ccgost/gost_eng.c b/engines/ccgost/gost_eng.c
index 4129260..fed3abe 100644
--- a/engines/ccgost/gost_eng.c
+++ b/engines/ccgost/gost_eng.c
@@ -39,8 +39,24 @@ static int gost_pkey_asn1_meths(ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth,
 
 static int gost_cipher_nids[] = { NID_id_Gost28147_89, NID_gost89_cnt, 0 };
 
-static int gost_digest_nids[] =
-    { NID_id_GostR3411_94, NID_id_Gost28147_89_MAC, 0 };
+static int gost_digest_nids(const int **nids)
+{
+    static int digest_nids[3] = { 0, 0, 0 };
+    static int pos = 0;
+    static int init = 0;
+
+    if (!init) {
+        const EVP_MD *md;
+        if ((md = digest_gost()) != NULL)
+            digest_nids[pos++] = EVP_MD_type(md);
+        if ((md = imit_gost_cpa()) != NULL)
+            digest_nids[pos++] = EVP_MD_type(md);
+        digest_nids[pos] = 0;
+        init = 1;
+    }
+    *nids = digest_nids;
+    return pos;
+}
 
 static EVP_PKEY_METHOD *pmeth_GostR3410_2001 = NULL;
 static EVP_PKEY_METHOD *pmeth_Gost28147_MAC = NULL;
@@ -60,6 +76,9 @@ static int gost_engine_finish(ENGINE *e)
 
 static int gost_engine_destroy(ENGINE *e)
 {
+    digest_gost_destroy();
+    imit_gost_cpa_destroy();
+
     gost_param_free();
 
     pmeth_GostR3410_2001 = NULL;
@@ -136,8 +155,8 @@ static int bind_gost(ENGINE *e, const char *id)
         /* These two actually should go in LIST_ADD command */
         || !EVP_add_cipher(&cipher_gost)
         || !EVP_add_cipher(&cipher_gost_cpacnt)
-        || !EVP_add_digest(&digest_gost)
-        || !EVP_add_digest(&imit_gost_cpa)
+        || !EVP_add_digest(digest_gost())
+        || !EVP_add_digest(imit_gost_cpa())
         ) {
         goto end;
     }
@@ -157,16 +176,15 @@ static int gost_digests(ENGINE *e, const EVP_MD **digest,
 {
     int ok = 1;
     if (!digest) {
-        *nids = gost_digest_nids;
-        return 2;
+        return gost_digest_nids(nids);
     }
     /*
      * printf("Digest no %d requested\n",nid);
      */
     if (nid == NID_id_GostR3411_94) {
-        *digest = &digest_gost;
+        *digest = digest_gost();
     } else if (nid == NID_id_Gost28147_89_MAC) {
-        *digest = &imit_gost_cpa;
+        *digest = imit_gost_cpa();
     } else {
         ok = 0;
         *digest = NULL;
diff --git a/engines/ccgost/gost_lcl.h b/engines/ccgost/gost_lcl.h
index b2541a7..1e047c6 100644
--- a/engines/ccgost/gost_lcl.h
+++ b/engines/ccgost/gost_lcl.h
@@ -143,9 +143,11 @@ struct ossl_gost_digest_ctx {
     gost_ctx cctx;
 };
 /* EVP_MD structure for GOST R 34.11 */
-extern EVP_MD digest_gost;
+EVP_MD *digest_gost(void);
+void digest_gost_destroy(void);
 /* EVP_MD structure for GOST 28147 in MAC mode */
-extern EVP_MD imit_gost_cpa;
+EVP_MD *imit_gost_cpa(void);
+void imit_gost_cpa_destroy(void);
 /* Cipher context used for EVP_CIPHER operation */
 struct ossl_gost_cipher_ctx {
     int paramNID;
diff --git a/engines/ccgost/gost_md.c b/engines/ccgost/gost_md.c
index 6c96a1b..8c12d00 100644
--- a/engines/ccgost/gost_md.c
+++ b/engines/ccgost/gost_md.c
@@ -19,24 +19,39 @@ static int gost_digest_final(EVP_MD_CTX *ctx, unsigned char *md);
 static int gost_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from);
 static int gost_digest_cleanup(EVP_MD_CTX *ctx);
 
-EVP_MD digest_gost = {
-    NID_id_GostR3411_94,
-    NID_undef,
-    32,
-    0,
-    gost_digest_init,
-    gost_digest_update,
-    gost_digest_final,
-    gost_digest_copy,
-    gost_digest_cleanup,
-    32,
-    sizeof(struct ossl_gost_digest_ctx),
-    NULL
-};
+static EVP_MD *_hidden_GostR3411_94_md = NULL;
+EVP_MD *digest_gost(void)
+{
+
+    if (_hidden_GostR3411_94_md == NULL) {
+        EVP_MD *md;
+
+        if ((md = EVP_MD_meth_new(NID_id_GostR3411_94, NID_undef)) == NULL
+            || !EVP_MD_meth_set_result_size(md, 32)
+            || !EVP_MD_meth_set_input_blocksize(md, 32)
+            || !EVP_MD_meth_set_app_datasize(md,
+                                             sizeof(struct ossl_gost_digest_ctx))
+            || !EVP_MD_meth_set_init(md, gost_digest_init)
+            || !EVP_MD_meth_set_update(md, gost_digest_update)
+            || !EVP_MD_meth_set_final(md, gost_digest_final)
+            || !EVP_MD_meth_set_copy(md, gost_digest_copy)
+            || !EVP_MD_meth_set_cleanup(md, gost_digest_cleanup)) {
+            EVP_MD_meth_free(md);
+            md = NULL;
+        }
+        _hidden_GostR3411_94_md = md;
+    }
+    return _hidden_GostR3411_94_md;
+}
+void digest_gost_destroy(void)
+{
+    EVP_MD_meth_free(_hidden_GostR3411_94_md);
+    _hidden_GostR3411_94_md = NULL;
+}
 
 int gost_digest_init(EVP_MD_CTX *ctx)
 {
-    struct ossl_gost_digest_ctx *c = ctx->md_data;
+    struct ossl_gost_digest_ctx *c = EVP_MD_CTX_md_data(ctx);
     memset(&(c->dctx), 0, sizeof(gost_hash_ctx));
     gost_init(&(c->cctx), &GostR3411_94_CryptoProParamSet);
     c->dctx.cipher_ctx = &(c->cctx);
@@ -45,20 +60,20 @@ int gost_digest_init(EVP_MD_CTX *ctx)
 
 int gost_digest_update(EVP_MD_CTX *ctx, const void *data, size_t count)
 {
-    return hash_block((gost_hash_ctx *) ctx->md_data, data, count);
+    return hash_block((gost_hash_ctx *) EVP_MD_CTX_md_data(ctx), data, count);
 }
 
 int gost_digest_final(EVP_MD_CTX *ctx, unsigned char *md)
 {
-    return finish_hash((gost_hash_ctx *) ctx->md_data, md);
+    return finish_hash((gost_hash_ctx *) EVP_MD_CTX_md_data(ctx), md);
 
 }
 
 int gost_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from)
 {
-    struct ossl_gost_digest_ctx *md_ctx = to->md_data;
-    if (to->md_data && from->md_data) {
-        memcpy(to->md_data, from->md_data,
+    struct ossl_gost_digest_ctx *md_ctx = EVP_MD_CTX_md_data(to);
+    if (EVP_MD_CTX_md_data(to) && EVP_MD_CTX_md_data(from)) {
+        memcpy(EVP_MD_CTX_md_data(to), EVP_MD_CTX_md_data(from),
                sizeof(struct ossl_gost_digest_ctx));
         md_ctx->dctx.cipher_ctx = &(md_ctx->cctx);
     }
@@ -67,7 +82,7 @@ int gost_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from)
 
 int gost_digest_cleanup(EVP_MD_CTX *ctx)
 {
-    if (ctx->md_data)
-        memset(ctx->md_data, 0, sizeof(struct ossl_gost_digest_ctx));
+    if (EVP_MD_CTX_md_data(ctx))
+        memset(EVP_MD_CTX_md_data(ctx), 0, sizeof(struct ossl_gost_digest_ctx));
     return 1;
 }
diff --git a/engines/ccgost/gost_pmeth.c b/engines/ccgost/gost_pmeth.c
index e70e297..7381c95 100644
--- a/engines/ccgost/gost_pmeth.c
+++ b/engines/ccgost/gost_pmeth.c
@@ -388,7 +388,8 @@ static int pkey_gost_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
             } else {
                 key = &(data->key);
             }
-            return mctx->digest->md_ctrl(mctx, EVP_MD_CTRL_SET_KEY, 32, key);
+            return EVP_MD_meth_get_ctrl(EVP_MD_CTX_md(mctx))
+                (mctx, EVP_MD_CTRL_SET_KEY, 32, key);
         }
     }
     return -2;
diff --git a/engines/e_dasync.c b/engines/e_dasync.c
index c31b43a..e22c614 100644
--- a/engines/e_dasync.c
+++ b/engines/e_dasync.c
@@ -80,8 +80,6 @@ void ENGINE_load_dasync(void);
 static int dasync_digests(ENGINE *e, const EVP_MD **digest,
                           const int **nids, int nid);
 
-static int dasync_digest_nids[] = { NID_sha1, 0 };
-
 static void dummy_pause_job(void);
 
 /* SHA1 */
@@ -90,19 +88,49 @@ static int dasync_sha1_update(EVP_MD_CTX *ctx, const void *data,
                              size_t count);
 static int dasync_sha1_final(EVP_MD_CTX *ctx, unsigned char *md);
 
-static const EVP_MD dasync_sha1 = {
-    NID_sha1,
-    NID_sha1WithRSAEncryption,
-    SHA_DIGEST_LENGTH,
-    EVP_MD_FLAG_DIGALGID_ABSENT,
-    dasync_sha1_init,
-    dasync_sha1_update,
-    dasync_sha1_final,
-    NULL,
-    NULL,
-    SHA_CBLOCK,
-    sizeof(EVP_MD *) + sizeof(SHA_CTX),
-};
+static EVP_MD *_hidden_sha1_md = NULL;
+static const EVP_MD *dasync_sha1(void)
+{
+    if (_hidden_sha1_md == NULL) {
+        EVP_MD *md;
+
+        if ((md = EVP_MD_meth_new(NID_sha1, NID_sha1WithRSAEncryption)) == NULL
+            || !EVP_MD_meth_set_result_size(md, SHA_DIGEST_LENGTH)
+            || !EVP_MD_meth_set_input_blocksize(md, SHA_CBLOCK)
+            || !EVP_MD_meth_set_app_datasize(md,
+                                             sizeof(EVP_MD *) + sizeof(SHA_CTX))
+            || !EVP_MD_meth_set_flags(md, EVP_MD_FLAG_DIGALGID_ABSENT)
+            || !EVP_MD_meth_set_init(md, dasync_sha1_init)
+            || !EVP_MD_meth_set_update(md, dasync_sha1_update)
+            || !EVP_MD_meth_set_final(md, dasync_sha1_final)) {
+            EVP_MD_meth_free(md);
+            md = NULL;
+        }
+        _hidden_sha1_md = md;
+    }
+    return _hidden_sha1_md;
+}
+static void destroy_digests(void)
+{
+    EVP_MD_meth_free(_hidden_sha1_md);
+    _hidden_sha1_md = NULL;
+}
+static int dasync_digest_nids(const int **nids)
+{
+    static int digest_nids[2] = { 0, 0 };
+    static int pos = 0;
+    static int init = 0;
+
+    if (!init) {
+        const EVP_MD *md;
+        if ((md = dasync_sha1()) != NULL)
+            digest_nids[pos++] = EVP_MD_type(md);
+        digest_nids[pos] = 0;
+        init = 1;
+    }
+    *nids = digest_nids;
+    return pos;
+}
 
 /* RSA */
 
@@ -207,6 +235,7 @@ static int dasync_finish(ENGINE *e)
 
 static int dasync_destroy(ENGINE *e)
 {
+    destroy_digests();
     ERR_unload_DASYNC_strings();
     return 1;
 }
@@ -217,14 +246,12 @@ static int dasync_digests(ENGINE *e, const EVP_MD **digest,
     int ok = 1;
     if (!digest) {
         /* We are returning a list of supported nids */
-        *nids = dasync_digest_nids;
-        return (sizeof(dasync_digest_nids) -
-                1) / sizeof(dasync_digest_nids[0]);
+        return dasync_digest_nids(nids);
     }
     /* We are being asked for a specific digest */
     switch (nid) {
     case NID_sha1:
-        *digest = &dasync_sha1;
+        *digest = dasync_sha1();
         break;
     default:
         ok = 0;
@@ -259,7 +286,7 @@ static void dummy_pause_job(void) {
  * implementation
  */
 #undef data
-#define data(ctx) ((SHA_CTX *)(ctx)->md_data)
+#define data(ctx) ((SHA_CTX *)EVP_MD_CTX_md_data(ctx))
 static int dasync_sha1_init(EVP_MD_CTX *ctx)
 {
     dummy_pause_job();
diff --git a/engines/e_ossltest.c b/engines/e_ossltest.c
index 94e53cd..5fdb23e 100644
--- a/engines/e_ossltest.c
+++ b/engines/e_ossltest.c
@@ -87,29 +87,34 @@ void ENGINE_load_ossltest(void);
 static int ossltest_digests(ENGINE *e, const EVP_MD **digest,
                           const int **nids, int nid);
 
-static int ossltest_digest_nids[] = {
-    NID_md5, NID_sha1, NID_sha256, NID_sha384, NID_sha512, 0
-};
-
 /* MD5 */
 static int digest_md5_init(EVP_MD_CTX *ctx);
 static int digest_md5_update(EVP_MD_CTX *ctx, const void *data,
                              size_t count);
 static int digest_md5_final(EVP_MD_CTX *ctx, unsigned char *md);
 
-static const EVP_MD digest_md5 = {
-    NID_md5,
-    NID_md5WithRSAEncryption,
-    MD5_DIGEST_LENGTH,
-    0,
-    digest_md5_init,
-    digest_md5_update,
-    digest_md5_final,
-    NULL,
-    NULL,
-    MD5_CBLOCK,
-    sizeof(EVP_MD *) + sizeof(MD5_CTX),
-};
+static EVP_MD *_hidden_md5_md = NULL;
+static const EVP_MD *digest_md5(void)
+{
+    if (_hidden_md5_md == NULL) {
+        EVP_MD *md;
+
+        if ((md = EVP_MD_meth_new(NID_md5, NID_md5WithRSAEncryption)) == NULL
+            || !EVP_MD_meth_set_result_size(md, MD5_DIGEST_LENGTH)
+            || !EVP_MD_meth_set_input_blocksize(md, MD5_CBLOCK)
+            || !EVP_MD_meth_set_app_datasize(md,
+                                             sizeof(EVP_MD *) + sizeof(MD5_CTX))
+            || !EVP_MD_meth_set_flags(md, 0)
+            || !EVP_MD_meth_set_init(md, digest_md5_init)
+            || !EVP_MD_meth_set_update(md, digest_md5_update)
+            || !EVP_MD_meth_set_final(md, digest_md5_final)) {
+            EVP_MD_meth_free(md);
+            md = NULL;
+        }
+        _hidden_md5_md = md;
+    }
+    return _hidden_md5_md;
+}
 
 /* SHA1 */
 static int digest_sha1_init(EVP_MD_CTX *ctx);
@@ -117,19 +122,28 @@ static int digest_sha1_update(EVP_MD_CTX *ctx, const void *data,
                               size_t count);
 static int digest_sha1_final(EVP_MD_CTX *ctx, unsigned char *md);
 
-static const EVP_MD digest_sha1 = {
-    NID_sha1,
-    NID_sha1WithRSAEncryption,
-    SHA_DIGEST_LENGTH,
-    EVP_MD_FLAG_DIGALGID_ABSENT,
-    digest_sha1_init,
-    digest_sha1_update,
-    digest_sha1_final,
-    NULL,
-    NULL,
-    SHA_CBLOCK,
-    sizeof(EVP_MD *) + sizeof(SHA_CTX),
-};
+static EVP_MD *_hidden_sha1_md = NULL;
+static const EVP_MD *digest_sha1(void)
+{
+    if (_hidden_sha1_md == NULL) {
+        EVP_MD *md;
+
+        if ((md = EVP_MD_meth_new(NID_sha1, NID_sha1WithRSAEncryption)) == NULL
+            || !EVP_MD_meth_set_result_size(md, SHA_DIGEST_LENGTH)
+            || !EVP_MD_meth_set_input_blocksize(md, SHA_CBLOCK)
+            || !EVP_MD_meth_set_app_datasize(md,
+                                             sizeof(EVP_MD *) + sizeof(SHA_CTX))
+            || !EVP_MD_meth_set_flags(md, EVP_MD_FLAG_DIGALGID_ABSENT)
+            || !EVP_MD_meth_set_init(md, digest_sha1_init)
+            || !EVP_MD_meth_set_update(md, digest_sha1_update)
+            || !EVP_MD_meth_set_final(md, digest_sha1_final)) {
+            EVP_MD_meth_free(md);
+            md = NULL;
+        }
+        _hidden_sha1_md = md;
+    }
+    return _hidden_sha1_md;
+}
 
 /* SHA256 */
 static int digest_sha256_init(EVP_MD_CTX *ctx);
@@ -137,19 +151,28 @@ static int digest_sha256_update(EVP_MD_CTX *ctx, const void *data,
                                 size_t count);
 static int digest_sha256_final(EVP_MD_CTX *ctx, unsigned char *md);
 
-static const EVP_MD digest_sha256 = {
-    NID_sha256,
-    NID_sha256WithRSAEncryption,
-    SHA256_DIGEST_LENGTH,
-    EVP_MD_FLAG_DIGALGID_ABSENT,
-    digest_sha256_init,
-    digest_sha256_update,
-    digest_sha256_final,
-    NULL,
-    NULL,
-    SHA256_CBLOCK,
-    sizeof(EVP_MD *) + sizeof(SHA256_CTX),
-};
+static EVP_MD *_hidden_sha256_md = NULL;
+static const EVP_MD *digest_sha256(void)
+{
+    if (_hidden_sha256_md == NULL) {
+        EVP_MD *md;
+
+        if ((md = EVP_MD_meth_new(NID_sha256, NID_sha256WithRSAEncryption)) == NULL
+            || !EVP_MD_meth_set_result_size(md, SHA256_DIGEST_LENGTH)
+            || !EVP_MD_meth_set_input_blocksize(md, SHA256_CBLOCK)
+            || !EVP_MD_meth_set_app_datasize(md,
+                                             sizeof(EVP_MD *) + sizeof(SHA256_CTX))
+            || !EVP_MD_meth_set_flags(md, EVP_MD_FLAG_DIGALGID_ABSENT)
+            || !EVP_MD_meth_set_init(md, digest_sha256_init)
+            || !EVP_MD_meth_set_update(md, digest_sha256_update)
+            || !EVP_MD_meth_set_final(md, digest_sha256_final)) {
+            EVP_MD_meth_free(md);
+            md = NULL;
+        }
+        _hidden_sha256_md = md;
+    }
+    return _hidden_sha256_md;
+}
 
 /* SHA384/SHA512 */
 static int digest_sha384_init(EVP_MD_CTX *ctx);
@@ -159,33 +182,87 @@ static int digest_sha512_update(EVP_MD_CTX *ctx, const void *data,
 static int digest_sha384_final(EVP_MD_CTX *ctx, unsigned char *md);
 static int digest_sha512_final(EVP_MD_CTX *ctx, unsigned char *md);
 
-static const EVP_MD digest_sha384 = {
-    NID_sha384,
-    NID_sha384WithRSAEncryption,
-    SHA384_DIGEST_LENGTH,
-    EVP_MD_FLAG_DIGALGID_ABSENT,
-    digest_sha384_init,
-    digest_sha512_update,
-    digest_sha384_final,
-    NULL,
-    NULL,
-    SHA512_CBLOCK,
-    sizeof(EVP_MD *) + sizeof(SHA512_CTX),
-};
-
-static const EVP_MD digest_sha512 = {
-    NID_sha512,
-    NID_sha512WithRSAEncryption,
-    SHA512_DIGEST_LENGTH,
-    EVP_MD_FLAG_DIGALGID_ABSENT,
-    digest_sha512_init,
-    digest_sha512_update,
-    digest_sha512_final,
-    NULL,
-    NULL,
-    SHA512_CBLOCK,
-    sizeof(EVP_MD *) + sizeof(SHA512_CTX),
-};
+static EVP_MD *_hidden_sha384_md = NULL;
+static const EVP_MD *digest_sha384(void)
+{
+    if (_hidden_sha384_md == NULL) {
+        EVP_MD *md;
+
+        if ((md = EVP_MD_meth_new(NID_sha384, NID_sha384WithRSAEncryption)) == NULL
+            || !EVP_MD_meth_set_result_size(md, SHA384_DIGEST_LENGTH)
+            || !EVP_MD_meth_set_input_blocksize(md, SHA512_CBLOCK)
+            || !EVP_MD_meth_set_app_datasize(md,
+                                             sizeof(EVP_MD *) + sizeof(SHA512_CTX))
+            || !EVP_MD_meth_set_flags(md, EVP_MD_FLAG_DIGALGID_ABSENT)
+            || !EVP_MD_meth_set_init(md, digest_sha384_init)
+            || !EVP_MD_meth_set_update(md, digest_sha512_update)
+            || !EVP_MD_meth_set_final(md, digest_sha384_final)) {
+            EVP_MD_meth_free(md);
+            md = NULL;
+        }
+        _hidden_sha384_md = md;
+    }
+    return _hidden_sha384_md;
+}
+static EVP_MD *_hidden_sha512_md = NULL;
+static const EVP_MD *digest_sha512(void)
+{
+    if (_hidden_sha512_md == NULL) {
+        EVP_MD *md;
+
+        if ((md = EVP_MD_meth_new(NID_sha512, NID_sha512WithRSAEncryption)) == NULL
+            || !EVP_MD_meth_set_result_size(md, SHA512_DIGEST_LENGTH)
+            || !EVP_MD_meth_set_input_blocksize(md, SHA512_CBLOCK)
+            || !EVP_MD_meth_set_app_datasize(md,
+                                             sizeof(EVP_MD *) + sizeof(SHA512_CTX))
+            || !EVP_MD_meth_set_flags(md, EVP_MD_FLAG_DIGALGID_ABSENT)
+            || !EVP_MD_meth_set_init(md, digest_sha512_init)
+            || !EVP_MD_meth_set_update(md, digest_sha512_update)
+            || !EVP_MD_meth_set_final(md, digest_sha512_final)) {
+            EVP_MD_meth_free(md);
+            md = NULL;
+        }
+        _hidden_sha512_md = md;
+    }
+    return _hidden_sha512_md;
+}
+static void destroy_digests(void)
+{
+    EVP_MD_meth_free(_hidden_md5_md);
+    _hidden_md5_md = NULL;
+    EVP_MD_meth_free(_hidden_sha1_md);
+    _hidden_sha1_md = NULL;
+    EVP_MD_meth_free(_hidden_sha256_md);
+    _hidden_sha256_md = NULL;
+    EVP_MD_meth_free(_hidden_sha384_md);
+    _hidden_sha384_md = NULL;
+    EVP_MD_meth_free(_hidden_sha512_md);
+    _hidden_sha512_md = NULL;
+}
+static int ossltest_digest_nids(const int **nids)
+{
+    static int digest_nids[6] = { 0, 0, 0, 0, 0, 0 };
+    static int pos = 0;
+    static int init = 0;
+
+    if (!init) {
+        const EVP_MD *md;
+        if ((md = digest_md5()) != NULL)
+            digest_nids[pos++] = EVP_MD_type(md);
+        if ((md = digest_sha1()) != NULL)
+            digest_nids[pos++] = EVP_MD_type(md);
+        if ((md = digest_sha256()) != NULL)
+            digest_nids[pos++] = EVP_MD_type(md);
+        if ((md = digest_sha384()) != NULL)
+            digest_nids[pos++] = EVP_MD_type(md);
+        if ((md = digest_sha512()) != NULL)
+            digest_nids[pos++] = EVP_MD_type(md);
+        digest_nids[pos] = 0;
+        init = 1;
+    }
+    *nids = digest_nids;
+    return pos;
+}
 
 /* Setup ciphers */
 static int ossltest_ciphers(ENGINE *, const EVP_CIPHER **,
@@ -287,6 +364,7 @@ static int ossltest_finish(ENGINE *e)
 
 static int ossltest_destroy(ENGINE *e)
 {
+    destroy_digests();
     ERR_unload_OSSLTEST_strings();
     return 1;
 }
@@ -297,26 +375,24 @@ static int ossltest_digests(ENGINE *e, const EVP_MD **digest,
     int ok = 1;
     if (!digest) {
         /* We are returning a list of supported nids */
-        *nids = ossltest_digest_nids;
-        return (sizeof(ossltest_digest_nids) -
-                1) / sizeof(ossltest_digest_nids[0]);
+        return ossltest_digest_nids(nids);
     }
     /* We are being asked for a specific digest */
     switch (nid) {
     case NID_md5:
-        *digest = &digest_md5;
+        *digest = digest_md5();
         break;
     case NID_sha1:
-        *digest = &digest_sha1;
+        *digest = digest_sha1();
         break;
     case NID_sha256:
-        *digest = &digest_sha256;
+        *digest = digest_sha256();
         break;
     case NID_sha384:
-        *digest = &digest_sha384;
+        *digest = digest_sha384();
         break;
     case NID_sha512:
-        *digest = &digest_sha512;
+        *digest = digest_sha512();
         break;
     default:
         ok = 0;
@@ -365,7 +441,7 @@ static void fill_known_data(unsigned char *md, unsigned int len)
  * the same value.
  */
 #undef data
-#define data(ctx) ((MD5_CTX *)(ctx)->md_data)
+#define data(ctx) ((MD5_CTX *)EVP_MD_CTX_md_data(ctx))
 static int digest_md5_init(EVP_MD_CTX *ctx)
 {
     return MD5_Init(data(ctx));
@@ -392,7 +468,7 @@ static int digest_md5_final(EVP_MD_CTX *ctx, unsigned char *md)
  * SHA1 implementation.
  */
 #undef data
-#define data(ctx) ((SHA_CTX *)(ctx)->md_data)
+#define data(ctx) ((SHA_CTX *)EVP_MD_CTX_md_data(ctx))
 static int digest_sha1_init(EVP_MD_CTX *ctx)
 {
     return SHA1_Init(data(ctx));
@@ -419,7 +495,7 @@ static int digest_sha1_final(EVP_MD_CTX *ctx, unsigned char *md)
  * SHA256 implementation.
  */
 #undef data
-#define data(ctx) ((SHA256_CTX *)(ctx)->md_data)
+#define data(ctx) ((SHA256_CTX *)EVP_MD_CTX_md_data(ctx))
 static int digest_sha256_init(EVP_MD_CTX *ctx)
 {
     return SHA256_Init(data(ctx));
@@ -446,7 +522,7 @@ static int digest_sha256_final(EVP_MD_CTX *ctx, unsigned char *md)
  * SHA384/512 implementation.
  */
 #undef data
-#define data(ctx) ((SHA512_CTX *)(ctx)->md_data)
+#define data(ctx) ((SHA512_CTX *)EVP_MD_CTX_md_data(ctx))
 static int digest_sha384_init(EVP_MD_CTX *ctx)
 {
     return SHA384_Init(data(ctx));
diff --git a/include/openssl/evp.h b/include/openssl/evp.h
index 910f39b..d8fbba1 100644
--- a/include/openssl/evp.h
+++ b/include/openssl/evp.h
@@ -148,21 +148,41 @@ struct evp_pkey_st {
 # define EVP_PKEY_MO_DECRYPT     0x0008
 
 # ifndef EVP_MD
-struct evp_md_st {
-    int type;
-    int pkey_type;
-    int md_size;
-    unsigned long flags;
-    int (*init) (EVP_MD_CTX *ctx);
-    int (*update) (EVP_MD_CTX *ctx, const void *data, size_t count);
-    int (*final) (EVP_MD_CTX *ctx, unsigned char *md);
-    int (*copy) (EVP_MD_CTX *to, const EVP_MD_CTX *from);
-    int (*cleanup) (EVP_MD_CTX *ctx);
-    int block_size;
-    int ctx_size;               /* how big does the ctx->md_data need to be */
-    /* control function */
-    int (*md_ctrl) (EVP_MD_CTX *ctx, int cmd, int p1, void *p2);
-} /* EVP_MD */ ;
+EVP_MD *EVP_MD_meth_new(int md_type, int pkey_type);
+EVP_MD *EVP_MD_meth_dup(const EVP_MD *md);
+void EVP_MD_meth_free(EVP_MD *md);
+
+int EVP_MD_meth_set_input_blocksize(EVP_MD *md, int blocksize);
+int EVP_MD_meth_set_result_size(EVP_MD *md, int resultsize);
+int EVP_MD_meth_set_app_datasize(EVP_MD *md, int datasize);
+int EVP_MD_meth_set_flags(EVP_MD *md, unsigned long flags);
+int EVP_MD_meth_set_init(EVP_MD *md, int (*init)(EVP_MD_CTX *ctx));
+int EVP_MD_meth_set_update(EVP_MD *md, int (*update)(EVP_MD_CTX *ctx,
+                                                     const void *data,
+                                                     size_t count));
+int EVP_MD_meth_set_final(EVP_MD *md, int (*final)(EVP_MD_CTX *ctx,
+                                                   unsigned char *md));
+int EVP_MD_meth_set_copy(EVP_MD *md, int (*copy)(EVP_MD_CTX *to,
+                                                 const EVP_MD_CTX *from));
+int EVP_MD_meth_set_cleanup(EVP_MD *md, int (*cleanup)(EVP_MD_CTX *ctx));
+int EVP_MD_meth_set_ctrl(EVP_MD *md, int (*ctrl)(EVP_MD_CTX *ctx, int cmd,
+                                                 int p1, void *p2));
+
+int EVP_MD_meth_get_input_blocksize(const EVP_MD *md);
+int EVP_MD_meth_get_result_size(const EVP_MD *md);
+int EVP_MD_meth_get_app_datasize(const EVP_MD *md);
+unsigned long EVP_MD_meth_get_flags(const EVP_MD *md);
+int (*EVP_MD_meth_get_init(const EVP_MD *md))(EVP_MD_CTX *ctx);
+int (*EVP_MD_meth_get_update(const EVP_MD *md))(EVP_MD_CTX *ctx,
+                                                const void *data,
+                                                size_t count);
+int (*EVP_MD_meth_get_final(const EVP_MD *md))(EVP_MD_CTX *ctx,
+                                               unsigned char *md);
+int (*EVP_MD_meth_get_copy(const EVP_MD *md))(EVP_MD_CTX *to,
+                                              const EVP_MD_CTX *from);
+int (*EVP_MD_meth_get_cleanup(const EVP_MD *md))(EVP_MD_CTX *ctx);
+int (*EVP_MD_meth_get_ctrl(const EVP_MD *md))(EVP_MD_CTX *ctx, int cmd,
+                                              int p1, void *p2);
 
 /* digest can only handle a single block */
 #  define EVP_MD_FLAG_ONESHOT     0x0001
@@ -197,18 +217,6 @@ struct evp_md_st {
 
 # endif                         /* !EVP_MD */
 
-struct evp_md_ctx_st {
-    const EVP_MD *digest;
-    ENGINE *engine;             /* functional reference if 'digest' is
-                                 * ENGINE-provided */
-    unsigned long flags;
-    void *md_data;
-    /* Public key context for sign/verify */
-    EVP_PKEY_CTX *pctx;
-    /* Update function: usually copied from EVP_MD */
-    int (*update) (EVP_MD_CTX *ctx, const void *data, size_t count);
-} /* EVP_MD_CTX */ ;
-
 /* values for EVP_MD_CTX flags */
 
 # define EVP_MD_CTX_FLAG_ONESHOT         0x0001/* digest update will be
@@ -467,15 +475,6 @@ typedef int (EVP_PBE_KEYGEN) (EVP_CIPHER_CTX *ctx, const char *pass,
 # define EVP_get_cipherbyobj(a) EVP_get_cipherbynid(OBJ_obj2nid(a))
 
 /* Macros to reduce FIPS dependencies: do NOT use in applications */
-# define M_EVP_MD_size(e)                ((e)->md_size)
-# define M_EVP_MD_block_size(e)          ((e)->block_size)
-# define M_EVP_MD_CTX_set_flags(ctx,flgs) ((ctx)->flags|=(flgs))
-# define M_EVP_MD_CTX_clear_flags(ctx,flgs) ((ctx)->flags&=~(flgs))
-# define M_EVP_MD_CTX_test_flags(ctx,flgs) ((ctx)->flags&(flgs))
-# define M_EVP_MD_type(e)                        ((e)->type)
-# define M_EVP_MD_CTX_type(e)            M_EVP_MD_type(M_EVP_MD_CTX_md(e))
-# define M_EVP_MD_CTX_md(e)                      ((e)->digest)
-
 # define M_EVP_CIPHER_nid(e)             ((e)->nid)
 # define M_EVP_CIPHER_CTX_iv_length(e)   ((e)->cipher->iv_len)
 # define M_EVP_CIPHER_CTX_flags(e)       ((e)->cipher->flags)
@@ -503,9 +502,16 @@ int EVP_MD_block_size(const EVP_MD *md);
 unsigned long EVP_MD_flags(const EVP_MD *md);
 
 const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx);
+int (*EVP_MD_CTX_update_fn(EVP_MD_CTX *ctx))(EVP_MD_CTX *ctx,
+                                             const void *data, size_t count);
+void EVP_MD_CTX_set_update_fn(EVP_MD_CTX *ctx,
+                              int (*update) (EVP_MD_CTX *ctx,
+                                             const void *data, size_t count));
 # define EVP_MD_CTX_size(e)              EVP_MD_size(EVP_MD_CTX_md(e))
 # define EVP_MD_CTX_block_size(e)        EVP_MD_block_size(EVP_MD_CTX_md(e))
 # define EVP_MD_CTX_type(e)              EVP_MD_type(EVP_MD_CTX_md(e))
+EVP_PKEY_CTX *EVP_MD_CTX_pkey_ctx(const EVP_MD_CTX *ctx);
+void *EVP_MD_CTX_md_data(const EVP_MD_CTX *ctx);
 
 int EVP_CIPHER_nid(const EVP_CIPHER *cipher);
 # define EVP_CIPHER_name(e)              OBJ_nid2sn(EVP_CIPHER_nid(e))
@@ -565,11 +571,15 @@ void BIO_set_md(BIO *, const EVP_MD *md);
 # define EVP_delete_digest_alias(alias) \
         OBJ_NAME_remove(alias,OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS);
 
-void EVP_MD_CTX_init(EVP_MD_CTX *ctx);
-int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx);
 int EVP_MD_CTX_ctrl(EVP_MD_CTX *ctx, int cmd, int p1, void *p2);
-EVP_MD_CTX *EVP_MD_CTX_create(void);
-void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx);
+EVP_MD_CTX *EVP_MD_CTX_new(void);
+int EVP_MD_CTX_reset(EVP_MD_CTX *ctx);
+void EVP_MD_CTX_free(EVP_MD_CTX *ctx);
+# ifdef OPENSSL_USE_DEPRECATED
+#  define EVP_MD_CTX_create()     EVP_MD_CTX_new()
+#  define EVP_MD_CTX_init(ctx)    EVP_MD_CTX_reset((ctx))
+#  define EVP_MD_CTX_destroy(ctx) EVP_MD_CTX_free((ctx))
+# endif
 /*__owur*/ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in);
 void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags);
 void EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, int flags);
diff --git a/include/openssl/hmac.h b/include/openssl/hmac.h
index 011e2ae..071e8b4 100644
--- a/include/openssl/hmac.h
+++ b/include/openssl/hmac.h
@@ -68,19 +68,10 @@
 extern "C" {
 #endif
 
-typedef struct hmac_ctx_st {
-    const EVP_MD *md;
-    EVP_MD_CTX md_ctx;
-    EVP_MD_CTX i_ctx;
-    EVP_MD_CTX o_ctx;
-    unsigned int key_length;
-    unsigned char key[HMAC_MAX_MD_CBLOCK];
-} HMAC_CTX;
-
-# define HMAC_size(e)    (EVP_MD_size((e)->md))
-
-void HMAC_CTX_init(HMAC_CTX *ctx);
-void HMAC_CTX_cleanup(HMAC_CTX *ctx);
+size_t HMAC_size(HMAC_CTX *e);
+HMAC_CTX *HMAC_CTX_new(void);
+int HMAC_CTX_reset(HMAC_CTX *ctx);
+void HMAC_CTX_free(HMAC_CTX *ctx);
 
 #ifdef OPENSSL_USE_DEPRECATED
 
diff --git a/include/openssl/ossl_typ.h b/include/openssl/ossl_typ.h
index 02749dd..e56bf80 100644
--- a/include/openssl/ossl_typ.h
+++ b/include/openssl/ossl_typ.h
@@ -137,6 +137,8 @@ typedef struct evp_pkey_asn1_method_st EVP_PKEY_ASN1_METHOD;
 typedef struct evp_pkey_method_st EVP_PKEY_METHOD;
 typedef struct evp_pkey_ctx_st EVP_PKEY_CTX;
 
+typedef struct hmac_ctx_st HMAC_CTX;
+
 typedef struct dh_st DH;
 typedef struct dh_method DH_METHOD;
 
diff --git a/include/openssl/pem.h b/include/openssl/pem.h
index f9e23d2..2746e0e 100644
--- a/include/openssl/pem.h
+++ b/include/openssl/pem.h
@@ -104,7 +104,7 @@ extern "C" {
    */
 typedef struct PEM_Encode_Seal_st {
     EVP_ENCODE_CTX encode;
-    EVP_MD_CTX md;
+    EVP_MD_CTX *md;
     EVP_CIPHER_CTX cipher;
 } PEM_ENCODE_SEAL_CTX;
 
diff --git a/ssl/record/ssl3_record.c b/ssl/record/ssl3_record.c
index 381872d..99c655e 100644
--- a/ssl/record/ssl3_record.c
+++ b/ssl/record/ssl3_record.c
@@ -791,7 +791,6 @@ int n_ssl3_mac(SSL *ssl, unsigned char *md, int send)
 {
     SSL3_RECORD *rec;
     unsigned char *mac_sec, *seq;
-    EVP_MD_CTX md_ctx;
     const EVP_MD_CTX *hash;
     unsigned char *p, rec_char;
     size_t md_size;
@@ -855,30 +854,33 @@ int n_ssl3_mac(SSL *ssl, unsigned char *md, int send)
     } else {
         unsigned int md_size_u;
         /* Chop the digest off the end :-) */
-        EVP_MD_CTX_init(&md_ctx);
+        EVP_MD_CTX *md_ctx = EVP_MD_CTX_new();
+
+        if (md_ctx == NULL)
+            return -1;
 
         rec_char = rec->type;
         p = md;
         s2n(rec->length, p);
-        if (EVP_MD_CTX_copy_ex(&md_ctx, hash) <= 0
-                || EVP_DigestUpdate(&md_ctx, mac_sec, md_size) <= 0
-                || EVP_DigestUpdate(&md_ctx, ssl3_pad_1, npad) <= 0
-                || EVP_DigestUpdate(&md_ctx, seq, 8) <= 0
-                || EVP_DigestUpdate(&md_ctx, &rec_char, 1) <= 0
-                || EVP_DigestUpdate(&md_ctx, md, 2) <= 0
-                || EVP_DigestUpdate(&md_ctx, rec->input, rec->length) <= 0
-                || EVP_DigestFinal_ex(&md_ctx, md, NULL) <= 0
-                || EVP_MD_CTX_copy_ex(&md_ctx, hash) <= 0
-                || EVP_DigestUpdate(&md_ctx, mac_sec, md_size) <= 0
-                || EVP_DigestUpdate(&md_ctx, ssl3_pad_2, npad) <= 0
-                || EVP_DigestUpdate(&md_ctx, md, md_size) <= 0
-                || EVP_DigestFinal_ex(&md_ctx, md, &md_size_u) <= 0) {
-            EVP_MD_CTX_cleanup(&md_ctx);
+        if (EVP_MD_CTX_copy_ex(md_ctx, hash) <= 0
+                || EVP_DigestUpdate(md_ctx, mac_sec, md_size) <= 0
+                || EVP_DigestUpdate(md_ctx, ssl3_pad_1, npad) <= 0
+                || EVP_DigestUpdate(md_ctx, seq, 8) <= 0
+                || EVP_DigestUpdate(md_ctx, &rec_char, 1) <= 0
+                || EVP_DigestUpdate(md_ctx, md, 2) <= 0
+                || EVP_DigestUpdate(md_ctx, rec->input, rec->length) <= 0
+                || EVP_DigestFinal_ex(md_ctx, md, NULL) <= 0
+                || EVP_MD_CTX_copy_ex(md_ctx, hash) <= 0
+                || EVP_DigestUpdate(md_ctx, mac_sec, md_size) <= 0
+                || EVP_DigestUpdate(md_ctx, ssl3_pad_2, npad) <= 0
+                || EVP_DigestUpdate(md_ctx, md, md_size) <= 0
+                || EVP_DigestFinal_ex(md_ctx, md, &md_size_u) <= 0) {
+            EVP_MD_CTX_reset(md_ctx);
             return -1;
         }
         md_size = md_size_u;
 
-        EVP_MD_CTX_cleanup(&md_ctx);
+        EVP_MD_CTX_free(md_ctx);
     }
 
     ssl3_record_sequence_update(seq);
@@ -892,7 +894,7 @@ int tls1_mac(SSL *ssl, unsigned char *md, int send)
     EVP_MD_CTX *hash;
     size_t md_size;
     int i;
-    EVP_MD_CTX hmac, *mac_ctx;
+    EVP_MD_CTX *hmac = NULL, *mac_ctx;
     unsigned char header[13];
     int stream_mac = (send ? (ssl->mac_flags & SSL_MAC_FLAG_WRITE_MAC_STREAM)
                       : (ssl->mac_flags & SSL_MAC_FLAG_READ_MAC_STREAM));
@@ -916,9 +918,11 @@ int tls1_mac(SSL *ssl, unsigned char *md, int send)
     if (stream_mac) {
         mac_ctx = hash;
     } else {
-        if (!EVP_MD_CTX_copy(&hmac, hash))
+        hmac = EVP_MD_CTX_new();
+        if (hmac == NULL
+                || !EVP_MD_CTX_copy(hmac, hash))
             return -1;
-        mac_ctx = &hmac;
+        mac_ctx = hmac;
     }
 
     if (SSL_IS_DTLS(ssl)) {
@@ -953,16 +957,14 @@ int tls1_mac(SSL *ssl, unsigned char *md, int send)
                                    rec->length + md_size, rec->orig_len,
                                    ssl->s3->read_mac_secret,
                                    ssl->s3->read_mac_secret_size, 0) <= 0) {
-            if (!stream_mac)
-                EVP_MD_CTX_cleanup(&hmac);
+            EVP_MD_CTX_free(hmac);
             return -1;
         }
     } else {
         if (EVP_DigestSignUpdate(mac_ctx, header, sizeof(header)) <= 0
                 || EVP_DigestSignUpdate(mac_ctx, rec->input, rec->length) <= 0
                 || EVP_DigestSignFinal(mac_ctx, md, &md_size) <= 0) {
-            if (!stream_mac)
-                EVP_MD_CTX_cleanup(&hmac);
+            EVP_MD_CTX_free(hmac);
             return -1;
         }
         if (!send && !SSL_USE_ETM(ssl) && FIPS_mode())
@@ -971,8 +973,7 @@ int tls1_mac(SSL *ssl, unsigned char *md, int send)
                                   rec->length, rec->orig_len);
     }
 
-    if (!stream_mac)
-        EVP_MD_CTX_cleanup(&hmac);
+    EVP_MD_CTX_free(hmac);
 
 #ifdef TLS_DEBUG
     fprintf(stderr, "seq=");
diff --git a/ssl/s3_cbc.c b/ssl/s3_cbc.c
index 177f6d7..f07a045 100644
--- a/ssl/s3_cbc.c
+++ b/ssl/s3_cbc.c
@@ -201,7 +201,7 @@ int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx,
     unsigned char first_block[MAX_HASH_BLOCK_SIZE];
     unsigned char mac_out[EVP_MAX_MD_SIZE];
     unsigned i, j, md_out_size_u;
-    EVP_MD_CTX md_ctx;
+    EVP_MD_CTX *md_ctx = NULL;
     /*
      * mdLengthSize is the number of bytes in the length field that
      * terminates * the hash.
@@ -497,34 +497,36 @@ int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx,
             mac_out[j] |= block[j] & is_block_b;
     }
 
-    EVP_MD_CTX_init(&md_ctx);
-    if (EVP_DigestInit_ex(&md_ctx, ctx->digest, NULL /* engine */ ) <= 0)
+    md_ctx = EVP_MD_CTX_new();
+    if (md_ctx == NULL)
+        goto err;
+    if (EVP_DigestInit_ex(md_ctx, EVP_MD_CTX_md(ctx), NULL /* engine */ ) <= 0)
         goto err;
     if (is_sslv3) {
         /* We repurpose |hmac_pad| to contain the SSLv3 pad2 block. */
         memset(hmac_pad, 0x5c, sslv3_pad_length);
 
-        if (EVP_DigestUpdate(&md_ctx, mac_secret, mac_secret_length) <= 0
-                || EVP_DigestUpdate(&md_ctx, hmac_pad, sslv3_pad_length) <= 0
-                || EVP_DigestUpdate(&md_ctx, mac_out, md_size) <= 0)
+        if (EVP_DigestUpdate(md_ctx, mac_secret, mac_secret_length) <= 0
+                || EVP_DigestUpdate(md_ctx, hmac_pad, sslv3_pad_length) <= 0
+                || EVP_DigestUpdate(md_ctx, mac_out, md_size) <= 0)
             goto err;
     } else {
         /* Complete the HMAC in the standard manner. */
         for (i = 0; i < md_block_size; i++)
             hmac_pad[i] ^= 0x6a;
 
-        if (EVP_DigestUpdate(&md_ctx, hmac_pad, md_block_size) <= 0
-                || EVP_DigestUpdate(&md_ctx, mac_out, md_size) <= 0)
+        if (EVP_DigestUpdate(md_ctx, hmac_pad, md_block_size) <= 0
+                || EVP_DigestUpdate(md_ctx, mac_out, md_size) <= 0)
             goto err;
     }
-    ret = EVP_DigestFinal(&md_ctx, md_out, &md_out_size_u);
+    ret = EVP_DigestFinal(md_ctx, md_out, &md_out_size_u);
     if (ret && md_out_size)
         *md_out_size = md_out_size_u;
-    EVP_MD_CTX_cleanup(&md_ctx);
+    EVP_MD_CTX_free(md_ctx);
 
     return 1;
 err:
-    EVP_MD_CTX_cleanup(&md_ctx);
+    EVP_MD_CTX_free(md_ctx);
     return 0;
 }
 
diff --git a/ssl/s3_enc.c b/ssl/s3_enc.c
index 31c8918..c20bff2 100644
--- a/ssl/s3_enc.c
+++ b/ssl/s3_enc.c
@@ -142,19 +142,24 @@
 
 static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num)
 {
-    EVP_MD_CTX m5;
-    EVP_MD_CTX s1;
+    EVP_MD_CTX *m5;
+    EVP_MD_CTX *s1;
     unsigned char buf[16], smd[SHA_DIGEST_LENGTH];
     unsigned char c = 'A';
     unsigned int i, j, k;
+    int ret = 0;
 
 #ifdef CHARSET_EBCDIC
     c = os_toascii[c];          /* 'A' in ASCII */
 #endif
     k = 0;
-    EVP_MD_CTX_init(&m5);
-    EVP_MD_CTX_set_flags(&m5, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
-    EVP_MD_CTX_init(&s1);
+    m5 = EVP_MD_CTX_new();
+    s1 = EVP_MD_CTX_new();
+    if (m5 == NULL || s1 == NULL) {
+        SSLerr(SSL_F_SSL3_GENERATE_KEY_BLOCK, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    EVP_MD_CTX_set_flags(m5, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
     for (i = 0; (int)i < num; i += MD5_DIGEST_LENGTH) {
         k++;
         if (k > sizeof buf) {
@@ -166,30 +171,32 @@ static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num)
         for (j = 0; j < k; j++)
             buf[j] = c;
         c++;
-        EVP_DigestInit_ex(&s1, EVP_sha1(), NULL);
-        EVP_DigestUpdate(&s1, buf, k);
-        EVP_DigestUpdate(&s1, s->session->master_key,
+        EVP_DigestInit_ex(s1, EVP_sha1(), NULL);
+        EVP_DigestUpdate(s1, buf, k);
+        EVP_DigestUpdate(s1, s->session->master_key,
                          s->session->master_key_length);
-        EVP_DigestUpdate(&s1, s->s3->server_random, SSL3_RANDOM_SIZE);
-        EVP_DigestUpdate(&s1, s->s3->client_random, SSL3_RANDOM_SIZE);
-        EVP_DigestFinal_ex(&s1, smd, NULL);
+        EVP_DigestUpdate(s1, s->s3->server_random, SSL3_RANDOM_SIZE);
+        EVP_DigestUpdate(s1, s->s3->client_random, SSL3_RANDOM_SIZE);
+        EVP_DigestFinal_ex(s1, smd, NULL);
 
-        EVP_DigestInit_ex(&m5, EVP_md5(), NULL);
-        EVP_DigestUpdate(&m5, s->session->master_key,
+        EVP_DigestInit_ex(m5, EVP_md5(), NULL);
+        EVP_DigestUpdate(m5, s->session->master_key,
                          s->session->master_key_length);
-        EVP_DigestUpdate(&m5, smd, SHA_DIGEST_LENGTH);
+        EVP_DigestUpdate(m5, smd, SHA_DIGEST_LENGTH);
         if ((int)(i + MD5_DIGEST_LENGTH) > num) {
-            EVP_DigestFinal_ex(&m5, smd, NULL);
+            EVP_DigestFinal_ex(m5, smd, NULL);
             memcpy(km, smd, (num - i));
         } else
-            EVP_DigestFinal_ex(&m5, km, NULL);
+            EVP_DigestFinal_ex(m5, km, NULL);
 
         km += MD5_DIGEST_LENGTH;
     }
     OPENSSL_cleanse(smd, sizeof(smd));
-    EVP_MD_CTX_cleanup(&m5);
-    EVP_MD_CTX_cleanup(&s1);
-    return 1;
+    ret = 1;
+ err:
+    EVP_MD_CTX_free(m5);
+    EVP_MD_CTX_free(s1);
+    return ret;
 }
 
 int ssl3_change_cipher_state(SSL *s, int which)
@@ -440,7 +447,7 @@ void ssl3_free_digest_list(SSL *s)
 {
     BIO_free(s->s3->handshake_buffer);
     s->s3->handshake_buffer = NULL;
-    EVP_MD_CTX_destroy(s->s3->handshake_dgst);
+    EVP_MD_CTX_free(s->s3->handshake_dgst);
     s->s3->handshake_dgst = NULL;
 }
 
@@ -465,7 +472,7 @@ int ssl3_digest_cached_records(SSL *s, int keep)
             return 0;
         }
 
-        s->s3->handshake_dgst = EVP_MD_CTX_create();
+        s->s3->handshake_dgst = EVP_MD_CTX_new();
         if (s->s3->handshake_dgst == NULL) {
             SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, ERR_R_MALLOC_FAILURE);
             return 0;
@@ -492,7 +499,7 @@ int ssl3_digest_cached_records(SSL *s, int keep)
 int ssl3_final_finish_mac(SSL *s, const char *sender, int len, unsigned char *p)
 {
     int ret;
-    EVP_MD_CTX ctx;
+    EVP_MD_CTX *ctx = NULL;
 
     if (!ssl3_digest_cached_records(s, 0))
         return 0;
@@ -502,25 +509,29 @@ int ssl3_final_finish_mac(SSL *s, const char *sender, int len, unsigned char *p)
         return 0;
     }
 
-    EVP_MD_CTX_init(&ctx);
-    EVP_MD_CTX_copy_ex(&ctx, s->s3->handshake_dgst);
+    ctx = EVP_MD_CTX_new();
+    if (ctx == NULL) {
+        SSLerr(SSL_F_SSL3_FINAL_FINISH_MAC, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    EVP_MD_CTX_copy_ex(ctx, s->s3->handshake_dgst);
 
-    ret = EVP_MD_CTX_size(&ctx);
+    ret = EVP_MD_CTX_size(ctx);
     if (ret < 0) {
-        EVP_MD_CTX_cleanup(&ctx);
+        EVP_MD_CTX_reset(ctx);
         return 0;
     }
 
-    if ((sender != NULL && EVP_DigestUpdate(&ctx, sender, len) <= 0)
-            || EVP_MD_CTX_ctrl(&ctx, EVP_CTRL_SSL3_MASTER_SECRET,
+    if ((sender != NULL && EVP_DigestUpdate(ctx, sender, len) <= 0)
+            || EVP_MD_CTX_ctrl(ctx, EVP_CTRL_SSL3_MASTER_SECRET,
                                s->session->master_key_length,
                                s->session->master_key) <= 0
-            || EVP_DigestFinal_ex(&ctx, p, NULL) <= 0) {
+            || EVP_DigestFinal_ex(ctx, p, NULL) <= 0) {
         SSLerr(SSL_F_SSL3_FINAL_FINISH_MAC, ERR_R_INTERNAL_ERROR);
         ret = 0;
     }
 
-    EVP_MD_CTX_cleanup(&ctx);
+    EVP_MD_CTX_free(ctx);
 
     return ret;
 }
@@ -540,29 +551,32 @@ int ssl3_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
 #endif
     };
     unsigned char buf[EVP_MAX_MD_SIZE];
-    EVP_MD_CTX ctx;
+    EVP_MD_CTX *ctx = EVP_MD_CTX_new();
     int i, ret = 0;
     unsigned int n;
 #ifdef OPENSSL_SSL_TRACE_CRYPTO
     unsigned char *tmpout = out;
 #endif
 
-    EVP_MD_CTX_init(&ctx);
+    if (ctx == NULL) {
+        SSLerr(SSL_F_SSL3_GENERATE_MASTER_SECRET, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
     for (i = 0; i < 3; i++) {
-        if (EVP_DigestInit_ex(&ctx, s->ctx->sha1, NULL) <= 0
-                || EVP_DigestUpdate(&ctx, salt[i],
+        if (EVP_DigestInit_ex(ctx, s->ctx->sha1, NULL) <= 0
+                || EVP_DigestUpdate(ctx, salt[i],
                                     strlen((const char *)salt[i])) <= 0
-                || EVP_DigestUpdate(&ctx, p, len) <= 0
-                || EVP_DigestUpdate(&ctx, &(s->s3->client_random[0]),
+                || EVP_DigestUpdate(ctx, p, len) <= 0
+                || EVP_DigestUpdate(ctx, &(s->s3->client_random[0]),
                                     SSL3_RANDOM_SIZE) <= 0
-                || EVP_DigestUpdate(&ctx, &(s->s3->server_random[0]),
+                || EVP_DigestUpdate(ctx, &(s->s3->server_random[0]),
                                     SSL3_RANDOM_SIZE) <= 0
-                || EVP_DigestFinal_ex(&ctx, buf, &n) <= 0
+                || EVP_DigestFinal_ex(ctx, buf, &n) <= 0
 
-                || EVP_DigestInit_ex(&ctx, s->ctx->md5, NULL) <= 0
-                || EVP_DigestUpdate(&ctx, p, len) <= 0
-                || EVP_DigestUpdate(&ctx, buf, n) <= 0
-                || EVP_DigestFinal_ex(&ctx, out, &n) <= 0) {
+                || EVP_DigestInit_ex(ctx, s->ctx->md5, NULL) <= 0
+                || EVP_DigestUpdate(ctx, p, len) <= 0
+                || EVP_DigestUpdate(ctx, buf, n) <= 0
+                || EVP_DigestFinal_ex(ctx, out, &n) <= 0) {
             SSLerr(SSL_F_SSL3_GENERATE_MASTER_SECRET, ERR_R_INTERNAL_ERROR);
             ret = 0;
             break;
@@ -570,7 +584,7 @@ int ssl3_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
         out += n;
         ret += n;
     }
-    EVP_MD_CTX_cleanup(&ctx);
+    EVP_MD_CTX_free(ctx);
 
 #ifdef OPENSSL_SSL_TRACE_CRYPTO
     if (ret > 0 && s->msg_callback) {
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index d51c6b7..3ca7c3f 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -3177,9 +3177,9 @@ void SSL_set_not_resumable_session_callback(SSL *ssl,
 EVP_MD_CTX *ssl_replace_hash(EVP_MD_CTX **hash, const EVP_MD *md)
 {
     ssl_clear_hash_ctx(hash);
-    *hash = EVP_MD_CTX_create();
+    *hash = EVP_MD_CTX_new();
     if (*hash == NULL || (md && EVP_DigestInit_ex(*hash, md, NULL) <= 0)) {
-        EVP_MD_CTX_destroy(*hash);
+        EVP_MD_CTX_free(*hash);
         *hash = NULL;
         return NULL;
     }
@@ -3190,26 +3190,30 @@ void ssl_clear_hash_ctx(EVP_MD_CTX **hash)
 {
 
     if (*hash)
-        EVP_MD_CTX_destroy(*hash);
+        EVP_MD_CTX_free(*hash);
     *hash = NULL;
 }
 
 /* Retrieve handshake hashes */
 int ssl_handshake_hash(SSL *s, unsigned char *out, int outlen)
 {
-    EVP_MD_CTX ctx;
+    EVP_MD_CTX *ctx = NULL;
     EVP_MD_CTX *hdgst = s->s3->handshake_dgst;
     int ret = EVP_MD_CTX_size(hdgst);
-    EVP_MD_CTX_init(&ctx);
     if (ret < 0 || ret > outlen) {
         ret = 0;
         goto err;
     }
-    if (!EVP_MD_CTX_copy_ex(&ctx, hdgst)
-        || EVP_DigestFinal_ex(&ctx, out, NULL) <= 0)
+    ctx = EVP_MD_CTX_new();
+    if (ctx == NULL) {
+        ret = 0;
+        goto err;
+    }
+    if (!EVP_MD_CTX_copy_ex(ctx, hdgst)
+        || EVP_DigestFinal_ex(ctx, out, NULL) <= 0)
         ret = 0;
  err:
-    EVP_MD_CTX_cleanup(&ctx);
+    EVP_MD_CTX_free(ctx);
     return ret;
 }
 
diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c
index 9ac9921..60c0983 100644
--- a/ssl/statem/statem_clnt.c
+++ b/ssl/statem/statem_clnt.c
@@ -1573,7 +1573,7 @@ MSG_PROCESS_RETURN tls_process_server_certificate(SSL *s, PACKET *pkt)
 
 MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt)
 {
-    EVP_MD_CTX md_ctx;
+    EVP_MD_CTX *md_ctx;
     int al, j;
     long alg_k, alg_a;
     EVP_PKEY *pkey = NULL;
@@ -1592,7 +1592,12 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt)
 #endif
     PACKET save_param_start, signature;
 
-    EVP_MD_CTX_init(&md_ctx);
+    md_ctx = EVP_MD_CTX_new();
+    if (md_ctx == NULL) {
+        al = SSL_AD_INTERNAL_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
+        goto f_err;
+    }
 
     alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
 
@@ -1882,18 +1887,18 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt)
             SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, SSL_R_WRONG_SIGNATURE_LENGTH);
             goto f_err;
         }
-        if (EVP_VerifyInit_ex(&md_ctx, md, NULL) <= 0
-                || EVP_VerifyUpdate(&md_ctx, &(s->s3->client_random[0]),
+        if (EVP_VerifyInit_ex(md_ctx, md, NULL) <= 0
+                || EVP_VerifyUpdate(md_ctx, &(s->s3->client_random[0]),
                                     SSL3_RANDOM_SIZE) <= 0
-                || EVP_VerifyUpdate(&md_ctx, &(s->s3->server_random[0]),
+                || EVP_VerifyUpdate(md_ctx, &(s->s3->server_random[0]),
                                     SSL3_RANDOM_SIZE) <= 0
-                || EVP_VerifyUpdate(&md_ctx, PACKET_data(&params),
+                || EVP_VerifyUpdate(md_ctx, PACKET_data(&params),
                                     PACKET_remaining(&params)) <= 0) {
             al = SSL_AD_INTERNAL_ERROR;
             SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_EVP_LIB);
             goto f_err;
         }
-        if (EVP_VerifyFinal(&md_ctx, PACKET_data(&signature),
+        if (EVP_VerifyFinal(md_ctx, PACKET_data(&signature),
                             PACKET_remaining(&signature), pkey) <= 0) {
             /* bad signature */
             al = SSL_AD_DECRYPT_ERROR;
@@ -1916,7 +1921,7 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt)
         }
     }
     EVP_PKEY_free(pkey);
-    EVP_MD_CTX_cleanup(&md_ctx);
+    EVP_MD_CTX_free(md_ctx);
     return MSG_PROCESS_CONTINUE_READING;
  f_err:
     ssl3_send_alert(s, SSL3_AL_FATAL, al);
@@ -1933,7 +1938,7 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt)
     EC_POINT_free(srvr_ecpoint);
     EC_KEY_free(ecdh);
 #endif
-    EVP_MD_CTX_cleanup(&md_ctx);
+    EVP_MD_CTX_free(md_ctx);
     ossl_statem_set_error(s);
     return MSG_PROCESS_ERROR;
 }
@@ -2716,7 +2721,7 @@ psk_err:
          * Compute shared IV and store it in algorithm-specific context
          * data
          */
-        ukm_hash = EVP_MD_CTX_create();
+        ukm_hash = EVP_MD_CTX_new();
         if (EVP_DigestInit(ukm_hash,
                            EVP_get_digestbynid(dgst_nid)) <= 0
                 || EVP_DigestUpdate(ukm_hash, s->s3->client_random,
@@ -2724,12 +2729,12 @@ psk_err:
                 || EVP_DigestUpdate(ukm_hash, s->s3->server_random,
                                     SSL3_RANDOM_SIZE) <= 0
                 || EVP_DigestFinal_ex(ukm_hash, shared_ukm, &md_len) <= 0) {
-            EVP_MD_CTX_destroy(ukm_hash);
+            EVP_MD_CTX_free(ukm_hash);
             SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE,
                    ERR_R_INTERNAL_ERROR);
             goto err;
         }
-        EVP_MD_CTX_destroy(ukm_hash);
+        EVP_MD_CTX_free(ukm_hash);
         if (EVP_PKEY_CTX_ctrl
             (pkey_ctx, -1, EVP_PKEY_OP_ENCRYPT, EVP_PKEY_CTRL_SET_IV, 8,
              shared_ukm) < 0) {
@@ -2894,13 +2899,17 @@ int tls_construct_client_verify(SSL *s)
     unsigned char *p;
     EVP_PKEY *pkey;
     const EVP_MD *md = s->s3->tmp.md[s->cert->key - s->cert->pkeys];
-    EVP_MD_CTX mctx;
+    EVP_MD_CTX *mctx;
     unsigned u = 0;
     unsigned long n = 0;
     long hdatalen = 0;
     void *hdata;
 
-    EVP_MD_CTX_init(&mctx);
+    mctx = EVP_MD_CTX_new();
+    if (mctx == NULL) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
 
     p = ssl_handshake_start(s);
     pkey = s->cert->key->privatekey;
@@ -2921,13 +2930,13 @@ int tls_construct_client_verify(SSL *s)
 #ifdef SSL_DEBUG
     fprintf(stderr, "Using client alg %s\n", EVP_MD_name(md));
 #endif
-    if (!EVP_SignInit_ex(&mctx, md, NULL)
-        || !EVP_SignUpdate(&mctx, hdata, hdatalen)
+    if (!EVP_SignInit_ex(mctx, md, NULL)
+        || !EVP_SignUpdate(mctx, hdata, hdatalen)
         || (s->version == SSL3_VERSION
-            && !EVP_MD_CTX_ctrl(&mctx, EVP_CTRL_SSL3_MASTER_SECRET,
+            && !EVP_MD_CTX_ctrl(mctx, EVP_CTRL_SSL3_MASTER_SECRET,
                                 s->session->master_key_length,
                                 s->session->master_key))
-        || !EVP_SignFinal(&mctx, p + 2, &u, pkey)) {
+        || !EVP_SignFinal(mctx, p + 2, &u, pkey)) {
         SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_EVP_LIB);
         goto err;
     }
@@ -2949,10 +2958,10 @@ int tls_construct_client_verify(SSL *s)
         goto err;
     }
 
-    EVP_MD_CTX_cleanup(&mctx);
+    EVP_MD_CTX_free(mctx);
     return 1;
  err:
-    EVP_MD_CTX_cleanup(&mctx);
+    EVP_MD_CTX_free(mctx);
     return 0;
 }
 
diff --git a/ssl/statem/statem_dtls.c b/ssl/statem/statem_dtls.c
index aafd28f..6d73659 100644
--- a/ssl/statem/statem_dtls.c
+++ b/ssl/statem/statem_dtls.c
@@ -204,8 +204,7 @@ void dtls1_hm_fragment_free(hm_fragment *frag)
     if (frag->msg_header.is_ccs) {
         EVP_CIPHER_CTX_free(frag->msg_header.
                             saved_retransmit_state.enc_write_ctx);
-        EVP_MD_CTX_destroy(frag->msg_header.
-                           saved_retransmit_state.write_hash);
+        EVP_MD_CTX_free(frag->msg_header.saved_retransmit_state.write_hash);
     }
     OPENSSL_free(frag->fragment);
     OPENSSL_free(frag->reassembly);
diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c
index a39e288..3ccb287 100644
--- a/ssl/statem/statem_srvr.c
+++ b/ssl/statem/statem_srvr.c
@@ -1733,9 +1733,13 @@ int tls_construct_server_key_exchange(SSL *s)
     BIGNUM *r[4];
     int nr[4], kn;
     BUF_MEM *buf;
-    EVP_MD_CTX md_ctx;
+    EVP_MD_CTX *md_ctx = EVP_MD_CTX_new();
 
-    EVP_MD_CTX_init(&md_ctx);
+    if (md_ctx == NULL) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
+        al = SSL_AD_INTERNAL_ERROR;
+        goto f_err;
+    }
 
     type = s->s3->tmp.new_cipher->algorithm_mkey;
     cert = s->cert;
@@ -2040,13 +2044,13 @@ int tls_construct_server_key_exchange(SSL *s)
 #ifdef SSL_DEBUG
             fprintf(stderr, "Using hash %s\n", EVP_MD_name(md));
 #endif
-            if (EVP_SignInit_ex(&md_ctx, md, NULL) <= 0
-                    || EVP_SignUpdate(&md_ctx, &(s->s3->client_random[0]),
+            if (EVP_SignInit_ex(md_ctx, md, NULL) <= 0
+                    || EVP_SignUpdate(md_ctx, &(s->s3->client_random[0]),
                                       SSL3_RANDOM_SIZE) <= 0
-                    || EVP_SignUpdate(&md_ctx, &(s->s3->server_random[0]),
+                    || EVP_SignUpdate(md_ctx, &(s->s3->server_random[0]),
                                       SSL3_RANDOM_SIZE) <= 0
-                    || EVP_SignUpdate(&md_ctx, d, n) <= 0
-                    || EVP_SignFinal(&md_ctx, &(p[2]),
+                    || EVP_SignUpdate(md_ctx, d, n) <= 0
+                    || EVP_SignFinal(md_ctx, &(p[2]),
                                (unsigned int *)&i, pkey) <= 0) {
                 SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_LIB_EVP);
                 al = SSL_AD_INTERNAL_ERROR;
@@ -2071,7 +2075,7 @@ int tls_construct_server_key_exchange(SSL *s)
         goto f_err;
     }
 
-    EVP_MD_CTX_cleanup(&md_ctx);
+    EVP_MD_CTX_free(md_ctx);
     return 1;
  f_err:
     ssl3_send_alert(s, SSL3_AL_FATAL, al);
@@ -2080,7 +2084,7 @@ int tls_construct_server_key_exchange(SSL *s)
     OPENSSL_free(encodedPoint);
     BN_CTX_free(bn_ctx);
 #endif
-    EVP_MD_CTX_cleanup(&md_ctx);
+    EVP_MD_CTX_free(md_ctx);
     ossl_statem_set_error(s);
     return 0;
 }
@@ -2884,8 +2888,13 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt)
     long hdatalen = 0;
     void *hdata;
 
-    EVP_MD_CTX mctx;
-    EVP_MD_CTX_init(&mctx);
+    EVP_MD_CTX *mctx = EVP_MD_CTX_new();
+
+    if (mctx == NULL) {
+        SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_MALLOC_FAILURE);
+        al = SSL_AD_INTERNAL_ERROR;
+        goto f_err;
+    }
 
     peer = s->session->peer;
     pkey = X509_get_pubkey(peer);
@@ -2966,8 +2975,8 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt)
 #ifdef SSL_DEBUG
     fprintf(stderr, "Using client verify alg %s\n", EVP_MD_name(md));
 #endif
-    if (!EVP_VerifyInit_ex(&mctx, md, NULL)
-        || !EVP_VerifyUpdate(&mctx, hdata, hdatalen)) {
+    if (!EVP_VerifyInit_ex(mctx, md, NULL)
+        || !EVP_VerifyUpdate(mctx, hdata, hdatalen)) {
         SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_EVP_LIB);
         al = SSL_AD_INTERNAL_ERROR;
         goto f_err;
@@ -2982,7 +2991,7 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt)
 #endif
 
     if (s->version == SSL3_VERSION
-        && !EVP_MD_CTX_ctrl(&mctx, EVP_CTRL_SSL3_MASTER_SECRET,
+        && !EVP_MD_CTX_ctrl(mctx, EVP_CTRL_SSL3_MASTER_SECRET,
                             s->session->master_key_length,
                             s->session->master_key)) {
         SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_EVP_LIB);
@@ -2990,7 +2999,7 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt)
         goto f_err;
     }
 
-    if (EVP_VerifyFinal(&mctx, data, len, pkey) <= 0) {
+    if (EVP_VerifyFinal(mctx, data, len, pkey) <= 0) {
         al = SSL_AD_DECRYPT_ERROR;
         SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_BAD_SIGNATURE);
         goto f_err;
@@ -3004,7 +3013,7 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt)
     }
     BIO_free(s->s3->handshake_buffer);
     s->s3->handshake_buffer = NULL;
-    EVP_MD_CTX_cleanup(&mctx);
+    EVP_MD_CTX_free(mctx);
     EVP_PKEY_free(pkey);
     return ret;
 }
@@ -3151,7 +3160,7 @@ int tls_construct_new_session_ticket(SSL *s)
 {
     unsigned char *senc = NULL;
     EVP_CIPHER_CTX ctx;
-    HMAC_CTX hctx;
+    HMAC_CTX *hctx = NULL;
     unsigned char *p, *macstart;
     const unsigned char *const_p;
     int len, slen_full, slen;
@@ -3178,7 +3187,7 @@ int tls_construct_new_session_ticket(SSL *s)
     }
 
     EVP_CIPHER_CTX_init(&ctx);
-    HMAC_CTX_init(&hctx);
+    hctx = HMAC_CTX_new();
 
     p = senc;
     if (!i2d_SSL_SESSION(s->session, &p))
@@ -3224,8 +3233,7 @@ int tls_construct_new_session_ticket(SSL *s)
      * all the work otherwise use generated values from parent ctx.
      */
     if (tctx->tlsext_ticket_key_cb) {
-        if (tctx->tlsext_ticket_key_cb(s, key_name, iv, &ctx,
-                                       &hctx, 1) < 0)
+        if (tctx->tlsext_ticket_key_cb(s, key_name, iv, &ctx, hctx, 1) < 0)
             goto err;
     } else {
         if (RAND_bytes(iv, 16) <= 0)
@@ -3233,7 +3241,7 @@ int tls_construct_new_session_ticket(SSL *s)
         if (!EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
                                 tctx->tlsext_tick_aes_key, iv))
             goto err;
-        if (!HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16,
+        if (!HMAC_Init_ex(hctx, tctx->tlsext_tick_hmac_key, 16,
                           EVP_sha256(), NULL))
             goto err;
         memcpy(key_name, tctx->tlsext_tick_key_name, 16);
@@ -3263,13 +3271,13 @@ int tls_construct_new_session_ticket(SSL *s)
         goto err;
     p += len;
 
-    if (!HMAC_Update(&hctx, macstart, p - macstart))
+    if (!HMAC_Update(hctx, macstart, p - macstart))
         goto err;
-    if (!HMAC_Final(&hctx, p, &hlen))
+    if (!HMAC_Final(hctx, p, &hlen))
         goto err;
 
     EVP_CIPHER_CTX_cleanup(&ctx);
-    HMAC_CTX_cleanup(&hctx);
+    HMAC_CTX_free(hctx);
 
     p += hlen;
     /* Now write out lengths: p points to end of data written */
@@ -3286,7 +3294,7 @@ int tls_construct_new_session_ticket(SSL *s)
  err:
     OPENSSL_free(senc);
     EVP_CIPHER_CTX_cleanup(&ctx);
-    HMAC_CTX_cleanup(&hctx);
+    HMAC_CTX_free(hctx);
     ossl_statem_set_error(s);
     return 0;
 }
diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c
index ccf933e..5889558 100644
--- a/ssl/t1_enc.c
+++ b/ssl/t1_enc.c
@@ -157,7 +157,7 @@ static int tls1_P_hash(const EVP_MD *md, const unsigned char *sec,
 {
     int chunk;
     size_t j;
-    EVP_MD_CTX ctx, ctx_tmp, ctx_init;
+    EVP_MD_CTX *ctx, *ctx_tmp, *ctx_init;
     EVP_PKEY *mac_key;
     unsigned char A1[EVP_MAX_MD_SIZE];
     size_t A1_len;
@@ -166,60 +166,62 @@ static int tls1_P_hash(const EVP_MD *md, const unsigned char *sec,
     chunk = EVP_MD_size(md);
     OPENSSL_assert(chunk >= 0);
 
-    EVP_MD_CTX_init(&ctx);
-    EVP_MD_CTX_init(&ctx_tmp);
-    EVP_MD_CTX_init(&ctx_init);
-    EVP_MD_CTX_set_flags(&ctx_init, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
+    ctx = EVP_MD_CTX_new();
+    ctx_tmp = EVP_MD_CTX_new();
+    ctx_init = EVP_MD_CTX_new();
+    if (ctx == NULL || ctx_tmp == NULL || ctx_init == NULL)
+        goto err;
+    EVP_MD_CTX_set_flags(ctx_init, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
     mac_key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, sec, sec_len);
     if (!mac_key)
         goto err;
-    if (!EVP_DigestSignInit(&ctx_init, NULL, md, NULL, mac_key))
+    if (!EVP_DigestSignInit(ctx_init, NULL, md, NULL, mac_key))
         goto err;
-    if (!EVP_MD_CTX_copy_ex(&ctx, &ctx_init))
+    if (!EVP_MD_CTX_copy_ex(ctx, ctx_init))
         goto err;
-    if (seed1 && !EVP_DigestSignUpdate(&ctx, seed1, seed1_len))
+    if (seed1 && !EVP_DigestSignUpdate(ctx, seed1, seed1_len))
         goto err;
-    if (seed2 && !EVP_DigestSignUpdate(&ctx, seed2, seed2_len))
+    if (seed2 && !EVP_DigestSignUpdate(ctx, seed2, seed2_len))
         goto err;
-    if (seed3 && !EVP_DigestSignUpdate(&ctx, seed3, seed3_len))
+    if (seed3 && !EVP_DigestSignUpdate(ctx, seed3, seed3_len))
         goto err;
-    if (seed4 && !EVP_DigestSignUpdate(&ctx, seed4, seed4_len))
+    if (seed4 && !EVP_DigestSignUpdate(ctx, seed4, seed4_len))
         goto err;
-    if (seed5 && !EVP_DigestSignUpdate(&ctx, seed5, seed5_len))
+    if (seed5 && !EVP_DigestSignUpdate(ctx, seed5, seed5_len))
         goto err;
-    if (!EVP_DigestSignFinal(&ctx, A1, &A1_len))
+    if (!EVP_DigestSignFinal(ctx, A1, &A1_len))
         goto err;
 
     for (;;) {
         /* Reinit mac contexts */
-        if (!EVP_MD_CTX_copy_ex(&ctx, &ctx_init))
+        if (!EVP_MD_CTX_copy_ex(ctx, ctx_init))
             goto err;
-        if (!EVP_DigestSignUpdate(&ctx, A1, A1_len))
+        if (!EVP_DigestSignUpdate(ctx, A1, A1_len))
             goto err;
-        if (olen > chunk && !EVP_MD_CTX_copy_ex(&ctx_tmp, &ctx))
+        if (olen > chunk && !EVP_MD_CTX_copy_ex(ctx_tmp, ctx))
             goto err;
-        if (seed1 && !EVP_DigestSignUpdate(&ctx, seed1, seed1_len))
+        if (seed1 && !EVP_DigestSignUpdate(ctx, seed1, seed1_len))
             goto err;
-        if (seed2 && !EVP_DigestSignUpdate(&ctx, seed2, seed2_len))
+        if (seed2 && !EVP_DigestSignUpdate(ctx, seed2, seed2_len))
             goto err;
-        if (seed3 && !EVP_DigestSignUpdate(&ctx, seed3, seed3_len))
+        if (seed3 && !EVP_DigestSignUpdate(ctx, seed3, seed3_len))
             goto err;
-        if (seed4 && !EVP_DigestSignUpdate(&ctx, seed4, seed4_len))
+        if (seed4 && !EVP_DigestSignUpdate(ctx, seed4, seed4_len))
             goto err;
-        if (seed5 && !EVP_DigestSignUpdate(&ctx, seed5, seed5_len))
+        if (seed5 && !EVP_DigestSignUpdate(ctx, seed5, seed5_len))
             goto err;
 
         if (olen > chunk) {
-            if (!EVP_DigestSignFinal(&ctx, out, &j))
+            if (!EVP_DigestSignFinal(ctx, out, &j))
                 goto err;
             out += j;
             olen -= j;
             /* calc the next A1 value */
-            if (!EVP_DigestSignFinal(&ctx_tmp, A1, &A1_len))
+            if (!EVP_DigestSignFinal(ctx_tmp, A1, &A1_len))
                 goto err;
         } else {                /* last one */
 
-            if (!EVP_DigestSignFinal(&ctx, A1, &A1_len))
+            if (!EVP_DigestSignFinal(ctx, A1, &A1_len))
                 goto err;
             memcpy(out, A1, olen);
             break;
@@ -228,9 +230,9 @@ static int tls1_P_hash(const EVP_MD *md, const unsigned char *sec,
     ret = 1;
  err:
     EVP_PKEY_free(mac_key);
-    EVP_MD_CTX_cleanup(&ctx);
-    EVP_MD_CTX_cleanup(&ctx_tmp);
-    EVP_MD_CTX_cleanup(&ctx_init);
+    EVP_MD_CTX_free(ctx);
+    EVP_MD_CTX_free(ctx_tmp);
+    EVP_MD_CTX_free(ctx_init);
     OPENSSL_cleanse(A1, sizeof(A1));
     return ret;
 }
@@ -372,7 +374,7 @@ int tls1_change_cipher_state(SSL *s, int which)
             goto err;
         dd = s->enc_write_ctx;
         if (SSL_IS_DTLS(s)) {
-            mac_ctx = EVP_MD_CTX_create();
+            mac_ctx = EVP_MD_CTX_new();
             if (mac_ctx == NULL)
                 goto err;
             s->write_hash = mac_ctx;
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index 971aad3..a6f2502 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -3027,6 +3027,7 @@ end:
  *       point to the resulting session.
  *
  * Returns:
+ *   -2: fatal error, malloc failure.
  *   -1: fatal error, either from parsing or decrypting the ticket.
  *    2: the ticket couldn't be decrypted.
  *    3: a ticket was successfully decrypted and *psess was set.
@@ -3041,19 +3042,21 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick,
     const unsigned char *p;
     int slen, mlen, renew_ticket = 0;
     unsigned char tick_hmac[EVP_MAX_MD_SIZE];
-    HMAC_CTX hctx;
+    HMAC_CTX *hctx = NULL;
     EVP_CIPHER_CTX ctx;
     SSL_CTX *tctx = s->initial_ctx;
     /* Need at least keyname + iv + some encrypted data */
     if (eticklen < 48)
         return 2;
     /* Initialize session ticket encryption and HMAC contexts */
-    HMAC_CTX_init(&hctx);
+    hctx = HMAC_CTX_new();
+    if (hctx == NULL)
+        return -2;
     EVP_CIPHER_CTX_init(&ctx);
     if (tctx->tlsext_ticket_key_cb) {
         unsigned char *nctick = (unsigned char *)etick;
         int rv = tctx->tlsext_ticket_key_cb(s, nctick, nctick + 16,
-                                            &ctx, &hctx, 0);
+                                            &ctx, hctx, 0);
         if (rv < 0)
             return -1;
         if (rv == 0)
@@ -3064,7 +3067,7 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick,
         /* Check key name matches */
         if (memcmp(etick, tctx->tlsext_tick_key_name, 16))
             return 2;
-        if (HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16,
+        if (HMAC_Init_ex(hctx, tctx->tlsext_tick_hmac_key, 16,
                          EVP_sha256(), NULL) <= 0
                 || EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
                                       tctx->tlsext_tick_aes_key,
@@ -3076,17 +3079,17 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick,
      * Attempt to process session ticket, first conduct sanity and integrity
      * checks on ticket.
      */
-    mlen = HMAC_size(&hctx);
+    mlen = HMAC_size(hctx);
     if (mlen < 0) {
         goto err;
     }
     eticklen -= mlen;
     /* Check HMAC of encrypted ticket */
-    if (HMAC_Update(&hctx, etick, eticklen) <= 0
-            || HMAC_Final(&hctx, tick_hmac, NULL) <= 0) {
+    if (HMAC_Update(hctx, etick, eticklen) <= 0
+            || HMAC_Final(hctx, tick_hmac, NULL) <= 0) {
         goto err;
     }
-    HMAC_CTX_cleanup(&hctx);
+    HMAC_CTX_free(hctx);
     if (CRYPTO_memcmp(tick_hmac, etick + eticklen, mlen)) {
         EVP_CIPHER_CTX_cleanup(&ctx);
         return 2;
@@ -3135,7 +3138,7 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick,
     return 2;
 err:
     EVP_CIPHER_CTX_cleanup(&ctx);
-    HMAC_CTX_cleanup(&hctx);
+    HMAC_CTX_free(hctx);
     return -1;
 }
 
diff --git a/test/ecdsatest.c b/test/ecdsatest.c
index d56836f..a55a553 100644
--- a/test/ecdsatest.c
+++ b/test/ecdsatest.c
@@ -188,17 +188,19 @@ int x9_62_test_internal(BIO *out, int nid, const char *r_in, const char *s_in)
     const char message[] = "abc";
     unsigned char digest[20];
     unsigned int dgst_len = 0;
-    EVP_MD_CTX md_ctx;
+    EVP_MD_CTX *md_ctx = EVP_MD_CTX_new();
     EC_KEY *key = NULL;
     ECDSA_SIG *signature = NULL;
     BIGNUM *r = NULL, *s = NULL;
     BIGNUM *kinv = NULL, *rp = NULL;
 
-    EVP_MD_CTX_init(&md_ctx);
+    if (md_ctx == NULL)
+        goto x962_int_err;
+
     /* get the message digest */
-    if (!EVP_DigestInit(&md_ctx, EVP_sha1())
-        || !EVP_DigestUpdate(&md_ctx, (const void *)message, 3)
-        || !EVP_DigestFinal(&md_ctx, digest, &dgst_len))
+    if (!EVP_DigestInit(md_ctx, EVP_sha1())
+        || !EVP_DigestUpdate(md_ctx, (const void *)message, 3)
+        || !EVP_DigestFinal(md_ctx, digest, &dgst_len))
         goto x962_int_err;
 
     BIO_printf(out, "testing %s: ", OBJ_nid2sn(nid));
@@ -244,7 +246,7 @@ int x9_62_test_internal(BIO *out, int nid, const char *r_in, const char *s_in)
     ECDSA_SIG_free(signature);
     BN_free(r);
     BN_free(s);
-    EVP_MD_CTX_cleanup(&md_ctx);
+    EVP_MD_CTX_free(md_ctx);
     BN_clear_free(kinv);
     BN_clear_free(rp);
     return ret;
diff --git a/test/evp_extra_test.c b/test/evp_extra_test.c
index ac79388..a536308 100644
--- a/test/evp_extra_test.c
+++ b/test/evp_extra_test.c
@@ -277,19 +277,21 @@ static int test_EVP_DigestSignInit(void)
     EVP_PKEY *pkey = NULL;
     unsigned char *sig = NULL;
     size_t sig_len = 0;
-    EVP_MD_CTX md_ctx, md_ctx_verify;
+    EVP_MD_CTX *md_ctx, *md_ctx_verify;
 
-    EVP_MD_CTX_init(&md_ctx);
-    EVP_MD_CTX_init(&md_ctx_verify);
+    md_ctx = EVP_MD_CTX_new();
+    md_ctx_verify = EVP_MD_CTX_new();
+    if (md_ctx == NULL || md_ctx_verify == NULL)
+        goto out;
 
     pkey = load_example_rsa_key();
     if (pkey == NULL ||
-        !EVP_DigestSignInit(&md_ctx, NULL, EVP_sha256(), NULL, pkey) ||
-        !EVP_DigestSignUpdate(&md_ctx, kMsg, sizeof(kMsg))) {
+        !EVP_DigestSignInit(md_ctx, NULL, EVP_sha256(), NULL, pkey) ||
+        !EVP_DigestSignUpdate(md_ctx, kMsg, sizeof(kMsg))) {
         goto out;
     }
     /* Determine the size of the signature. */
-    if (!EVP_DigestSignFinal(&md_ctx, NULL, &sig_len)) {
+    if (!EVP_DigestSignFinal(md_ctx, NULL, &sig_len)) {
         goto out;
     }
     /* Sanity check for testing. */
@@ -299,14 +301,14 @@ static int test_EVP_DigestSignInit(void)
     }
 
     sig = OPENSSL_malloc(sig_len);
-    if (sig == NULL || !EVP_DigestSignFinal(&md_ctx, sig, &sig_len)) {
+    if (sig == NULL || !EVP_DigestSignFinal(md_ctx, sig, &sig_len)) {
         goto out;
     }
 
     /* Ensure that the signature round-trips. */
-    if (!EVP_DigestVerifyInit(&md_ctx_verify, NULL, EVP_sha256(), NULL, pkey)
-        || !EVP_DigestVerifyUpdate(&md_ctx_verify, kMsg, sizeof(kMsg))
-        || !EVP_DigestVerifyFinal(&md_ctx_verify, sig, sig_len)) {
+    if (!EVP_DigestVerifyInit(md_ctx_verify, NULL, EVP_sha256(), NULL, pkey)
+        || !EVP_DigestVerifyUpdate(md_ctx_verify, kMsg, sizeof(kMsg))
+        || !EVP_DigestVerifyFinal(md_ctx_verify, sig, sig_len)) {
         goto out;
     }
 
@@ -317,8 +319,8 @@ static int test_EVP_DigestSignInit(void)
         ERR_print_errors_fp(stderr);
     }
 
-    EVP_MD_CTX_cleanup(&md_ctx);
-    EVP_MD_CTX_cleanup(&md_ctx_verify);
+    EVP_MD_CTX_free(md_ctx);
+    EVP_MD_CTX_free(md_ctx_verify);
     EVP_PKEY_free(pkey);
     OPENSSL_free(sig);
 
@@ -329,15 +331,15 @@ static int test_EVP_DigestVerifyInit(void)
 {
     int ret = 0;
     EVP_PKEY *pkey = NULL;
-    EVP_MD_CTX md_ctx;
+    EVP_MD_CTX *md_ctx;
 
-    EVP_MD_CTX_init(&md_ctx);
+    md_ctx = EVP_MD_CTX_new();
 
     pkey = load_example_rsa_key();
     if (pkey == NULL ||
-        !EVP_DigestVerifyInit(&md_ctx, NULL, EVP_sha256(), NULL, pkey) ||
-        !EVP_DigestVerifyUpdate(&md_ctx, kMsg, sizeof(kMsg)) ||
-        !EVP_DigestVerifyFinal(&md_ctx, kSignature, sizeof(kSignature))) {
+        !EVP_DigestVerifyInit(md_ctx, NULL, EVP_sha256(), NULL, pkey) ||
+        !EVP_DigestVerifyUpdate(md_ctx, kMsg, sizeof(kMsg)) ||
+        !EVP_DigestVerifyFinal(md_ctx, kSignature, sizeof(kSignature))) {
         goto out;
     }
     ret = 1;
@@ -347,7 +349,7 @@ static int test_EVP_DigestVerifyInit(void)
         ERR_print_errors_fp(stderr);
     }
 
-    EVP_MD_CTX_cleanup(&md_ctx);
+    EVP_MD_CTX_free(md_ctx);
     EVP_PKEY_free(pkey);
 
     return ret;
diff --git a/test/evp_test.c b/test/evp_test.c
index 83d1749..725af8a 100644
--- a/test/evp_test.c
+++ b/test/evp_test.c
@@ -691,7 +691,7 @@ static int digest_test_run(struct evp_test *t)
     EVP_MD_CTX *mctx;
     unsigned char md[EVP_MAX_MD_SIZE];
     unsigned int md_len;
-    mctx = EVP_MD_CTX_create();
+    mctx = EVP_MD_CTX_new();
     if (!mctx)
         goto err;
     err = "DIGESTINIT_ERROR";
@@ -713,8 +713,7 @@ static int digest_test_run(struct evp_test *t)
         goto err;
     err = NULL;
  err:
-    if (mctx)
-        EVP_MD_CTX_destroy(mctx);
+    EVP_MD_CTX_free(mctx);
     t->err = err;
     return 1;
 }
@@ -1101,7 +1100,7 @@ static int mac_test_run(struct evp_test *t)
         if (!md)
             goto err;
     }
-    mctx = EVP_MD_CTX_create();
+    mctx = EVP_MD_CTX_new();
     if (!mctx)
         goto err;
     err = "DIGESTSIGNINIT_ERROR";
@@ -1129,8 +1128,7 @@ static int mac_test_run(struct evp_test *t)
         goto err;
     err = NULL;
  err:
-    if (mctx)
-        EVP_MD_CTX_destroy(mctx);
+    EVP_MD_CTX_free(mctx);
     OPENSSL_free(mac);
     EVP_PKEY_CTX_free(genctx);
     EVP_PKEY_free(key);
diff --git a/test/gost2814789test.c b/test/gost2814789test.c
index 56a8ae3..2ab0782 100644
--- a/test/gost2814789test.c
+++ b/test/gost2814789test.c
@@ -1207,7 +1207,7 @@ int main(int argc, char *argv[])
     u64 ullMaxLen = 6 * 1000 * 1000;
     int ignore = 0;
     ENGINE *impl = NULL;
-    EVP_MD_CTX mctx;
+    EVP_MD_CTX *mctx;
     EVP_CIPHER_CTX ectx;
     EVP_PKEY *mac_key;
     byte bDerive[EVP_MAX_KEY_LENGTH];
@@ -1391,28 +1391,33 @@ int main(int argc, char *argv[])
                  */
                 continue;
             }
-            EVP_MD_CTX_init(&mctx);
+            mctx = EVP_MD_CTX_new();
+            if (mctx == NULL) {
+                fflush(NULL);
+                fprintf(stderr, "ENGINE_ctrl_cmd_string: malloc failure\n");
+                return 14;
+            }
             mac_key = EVP_PKEY_new_mac_key(NID_id_Gost28147_89_MAC, NULL,
                                            bDerive, mdl);
-            EVP_DigestSignInit(&mctx, NULL, md_g89imit, impl, mac_key);
+            EVP_DigestSignInit(mctx, NULL, md_g89imit, impl, mac_key);
             if (G89_MAX_TC_LEN >= tcs[t].ullLen) {
-                EVP_DigestSignUpdate(&mctx, tcs[t].bIn,
+                EVP_DigestSignUpdate(mctx, tcs[t].bIn,
                                      (unsigned int)tcs[t].ullLen);
             } else {
                 for (ullLeft = tcs[t].ullLen;
                      ullLeft >= sizeof(bZB); ullLeft -= sizeof(bZB)) {
                     printf("B");
                     fflush(NULL);
-                    EVP_DigestSignUpdate(&mctx, bZB, sizeof(bZB));
+                    EVP_DigestSignUpdate(mctx, bZB, sizeof(bZB));
                 }
                 printf("b" FMT64 "/" FMT64, ullLeft, tcs[t].ullLen);
                 fflush(NULL);
-                EVP_DigestSignUpdate(&mctx, bZB, (unsigned int)ullLeft);
+                EVP_DigestSignUpdate(mctx, bZB, (unsigned int)ullLeft);
             }
             siglen = 4;
-            OPENSSL_assert(EVP_DigestSignFinal(&mctx, bTest, &siglen));
+            OPENSSL_assert(EVP_DigestSignFinal(mctx, bTest, &siglen));
             EVP_PKEY_free(mac_key);
-            EVP_MD_CTX_cleanup(&mctx);
+            EVP_MD_CTX_free(mctx);
             enlu = (int)tcs[t].ullLen;
             enlf = 0;
             l = siglen;
diff --git a/test/hmactest.c b/test/hmactest.c
index f8d5350..9fb12ad 100644
--- a/test/hmactest.c
+++ b/test/hmactest.c
@@ -134,7 +134,7 @@ int main(int argc, char *argv[])
     char *p;
 # endif
     int err = 0;
-    HMAC_CTX ctx, ctx2;
+    HMAC_CTX *ctx = NULL, *ctx2 = NULL;
     unsigned char buf[EVP_MAX_MD_SIZE];
     unsigned int len;
 
@@ -165,57 +165,61 @@ int main(int argc, char *argv[])
 # endif                         /* OPENSSL_NO_MD5 */
 
 /* test4 */
-    HMAC_CTX_init(&ctx);
-    if (HMAC_Init_ex(&ctx, NULL, 0, NULL, NULL)) {
+    ctx = HMAC_CTX_new();
+    if (ctx == NULL) {
+        printf("HMAC malloc failure (test 4)\n");
+        err++;
+        goto end;
+    }
+    if (HMAC_Init_ex(ctx, NULL, 0, NULL, NULL)) {
         printf("Should fail to initialise HMAC with empty MD and key (test 4)\n");
         err++;
         goto test5;
     }
-    if (HMAC_Update(&ctx, test[4].data, test[4].data_len)) {
+    if (HMAC_Update(ctx, test[4].data, test[4].data_len)) {
         printf("Should fail HMAC_Update with ctx not set up (test 4)\n");
         err++;
         goto test5;
     }
-    if (HMAC_Init_ex(&ctx, NULL, 0, EVP_sha1(), NULL)) {
+    if (HMAC_Init_ex(ctx, NULL, 0, EVP_sha1(), NULL)) {
         printf("Should fail to initialise HMAC with empty key (test 4)\n");
         err++;
         goto test5;
     }
-    if (HMAC_Update(&ctx, test[4].data, test[4].data_len)) {
+    if (HMAC_Update(ctx, test[4].data, test[4].data_len)) {
         printf("Should fail HMAC_Update with ctx not set up (test 4)\n");
         err++;
         goto test5;
     }
     printf("test 4 ok\n");
 test5:
-    HMAC_CTX_cleanup(&ctx);
-    HMAC_CTX_init(&ctx);
-    if (HMAC_Init_ex(&ctx, test[4].key, test[4].key_len, NULL, NULL)) {
+    HMAC_CTX_reset(ctx);
+    if (HMAC_Init_ex(ctx, test[4].key, test[4].key_len, NULL, NULL)) {
         printf("Should fail to initialise HMAC with empty MD (test 5)\n");
         err++;
         goto test6;
     }
-    if (HMAC_Update(&ctx, test[4].data, test[4].data_len)) {
+    if (HMAC_Update(ctx, test[4].data, test[4].data_len)) {
         printf("Should fail HMAC_Update with ctx not set up (test 5)\n");
         err++;
         goto test6;
     }
-    if (HMAC_Init_ex(&ctx, test[4].key, -1, EVP_sha1(), NULL)) {
+    if (HMAC_Init_ex(ctx, test[4].key, -1, EVP_sha1(), NULL)) {
         printf("Should fail to initialise HMAC with invalid key len(test 5)\n");
         err++;
         goto test6;
     }
-    if (!HMAC_Init_ex(&ctx, test[4].key, test[4].key_len, EVP_sha1(), NULL)) {
+    if (!HMAC_Init_ex(ctx, test[4].key, test[4].key_len, EVP_sha1(), NULL)) {
         printf("Failed to initialise HMAC (test 5)\n");
         err++;
         goto test6;
     }
-    if (!HMAC_Update(&ctx, test[4].data, test[4].data_len)) {
+    if (!HMAC_Update(ctx, test[4].data, test[4].data_len)) {
         printf("Error updating HMAC with data (test 5)\n");
         err++;
         goto test6;
     }
-    if (!HMAC_Final(&ctx, buf, &len)) {
+    if (!HMAC_Final(ctx, buf, &len)) {
         printf("Error finalising data (test 5)\n");
         err++;
         goto test6;
@@ -227,22 +231,22 @@ test5:
         err++;
         goto test6;
     }
-    if (HMAC_Init_ex(&ctx, NULL, 0, EVP_sha256(), NULL)) {
+    if (HMAC_Init_ex(ctx, NULL, 0, EVP_sha256(), NULL)) {
         printf("Should disallow changing MD without a new key (test 5)\n");
         err++;
         goto test6;
     }
-    if (!HMAC_Init_ex(&ctx, test[4].key, test[4].key_len, EVP_sha256(), NULL)) {
+    if (!HMAC_Init_ex(ctx, test[4].key, test[4].key_len, EVP_sha256(), NULL)) {
         printf("Failed to reinitialise HMAC (test 5)\n");
         err++;
         goto test6;
     }
-    if (!HMAC_Update(&ctx, test[5].data, test[5].data_len)) {
+    if (!HMAC_Update(ctx, test[5].data, test[5].data_len)) {
         printf("Error updating HMAC with data (sha256) (test 5)\n");
         err++;
         goto test6;
     }
-    if (!HMAC_Final(&ctx, buf, &len)) {
+    if (!HMAC_Final(ctx, buf, &len)) {
         printf("Error finalising data (sha256) (test 5)\n");
         err++;
         goto test6;
@@ -254,17 +258,17 @@ test5:
         err++;
         goto test6;
     }
-    if (!HMAC_Init_ex(&ctx, test[6].key, test[6].key_len, NULL, NULL)) {
+    if (!HMAC_Init_ex(ctx, test[6].key, test[6].key_len, NULL, NULL)) {
         printf("Failed to reinitialise HMAC with key (test 5)\n");
         err++;
         goto test6;
     }
-    if (!HMAC_Update(&ctx, test[6].data, test[6].data_len)) {
+    if (!HMAC_Update(ctx, test[6].data, test[6].data_len)) {
         printf("Error updating HMAC with data (new key) (test 5)\n");
         err++;
         goto test6;
     }
-    if (!HMAC_Final(&ctx, buf, &len)) {
+    if (!HMAC_Final(ctx, buf, &len)) {
         printf("Error finalising data (new key) (test 5)\n");
         err++;
         goto test6;
@@ -278,24 +282,29 @@ test5:
         printf("test 5 ok\n");
     }
 test6:
-    HMAC_CTX_cleanup(&ctx);
-    HMAC_CTX_init(&ctx);
-    if (!HMAC_Init_ex(&ctx, test[7].key, test[7].key_len, EVP_sha1(), NULL)) {
+    HMAC_CTX_reset(ctx);
+    ctx2 = HMAC_CTX_new();
+    if (ctx2 == NULL) {
+        printf("HMAC malloc failure (test 6)\n");
+        err++;
+        goto end;
+    }
+    if (!HMAC_Init_ex(ctx, test[7].key, test[7].key_len, EVP_sha1(), NULL)) {
         printf("Failed to initialise HMAC (test 6)\n");
         err++;
         goto end;
     }
-    if (!HMAC_Update(&ctx, test[7].data, test[7].data_len)) {
+    if (!HMAC_Update(ctx, test[7].data, test[7].data_len)) {
         printf("Error updating HMAC with data (test 6)\n");
         err++;
         goto end;
     }
-    if (!HMAC_CTX_copy(&ctx2, &ctx)) {
+    if (!HMAC_CTX_copy(ctx2, ctx)) {
         printf("Failed to copy HMAC_CTX (test 6)\n");
         err++;
         goto end;
     }
-    if (!HMAC_Final(&ctx2, buf, &len)) {
+    if (!HMAC_Final(ctx2, buf, &len)) {
         printf("Error finalising data (test 6)\n");
         err++;
         goto end;
@@ -309,7 +318,8 @@ test6:
         printf("test 6 ok\n");
     }
 end:
-    HMAC_CTX_cleanup(&ctx);
+    HMAC_CTX_free(ctx2);
+    HMAC_CTX_free(ctx);
     EXIT(err);
 }
 
diff --git a/test/mdc2test.c b/test/mdc2test.c
index a0d77a3..938a3c1 100644
--- a/test/mdc2test.c
+++ b/test/mdc2test.c
@@ -95,17 +95,17 @@ int main(int argc, char *argv[])
     int ret = 0;
     unsigned char md[MDC2_DIGEST_LENGTH];
     int i;
-    EVP_MD_CTX c;
+    EVP_MD_CTX *c;
     static char *text = "Now is the time for all ";
 
 # ifdef CHARSET_EBCDIC
     ebcdic2ascii(text, text, strlen(text));
 # endif
 
-    EVP_MD_CTX_init(&c);
-    EVP_DigestInit_ex(&c, EVP_mdc2(), NULL);
-    EVP_DigestUpdate(&c, (unsigned char *)text, strlen(text));
-    EVP_DigestFinal_ex(&c, &(md[0]), NULL);
+    c = EVP_MD_CTX_new();
+    EVP_DigestInit_ex(c, EVP_mdc2(), NULL);
+    EVP_DigestUpdate(c, (unsigned char *)text, strlen(text));
+    EVP_DigestFinal_ex(c, &(md[0]), NULL);
 
     if (memcmp(md, pad1, MDC2_DIGEST_LENGTH) != 0) {
         for (i = 0; i < MDC2_DIGEST_LENGTH; i++)
@@ -118,11 +118,11 @@ int main(int argc, char *argv[])
     } else
         printf("pad1 - ok\n");
 
-    EVP_DigestInit_ex(&c, EVP_mdc2(), NULL);
+    EVP_DigestInit_ex(c, EVP_mdc2(), NULL);
     /* FIXME: use a ctl function? */
-    ((MDC2_CTX *)c.md_data)->pad_type = 2;
-    EVP_DigestUpdate(&c, (unsigned char *)text, strlen(text));
-    EVP_DigestFinal_ex(&c, &(md[0]), NULL);
+    ((MDC2_CTX *)EVP_MD_CTX_md_data(c))->pad_type = 2;
+    EVP_DigestUpdate(c, (unsigned char *)text, strlen(text));
+    EVP_DigestFinal_ex(c, &(md[0]), NULL);
 
     if (memcmp(md, pad2, MDC2_DIGEST_LENGTH) != 0) {
         for (i = 0; i < MDC2_DIGEST_LENGTH; i++)
@@ -135,7 +135,7 @@ int main(int argc, char *argv[])
     } else
         printf("pad2 - ok\n");
 
-    EVP_MD_CTX_cleanup(&c);
+    EVP_MD_CTX_free(c);
 # ifdef OPENSSL_SYS_NETWARE
     if (ret)
         printf("ERROR: %d\n", ret);
diff --git a/test/sha1test.c b/test/sha1test.c
index cc3633d..676cc84 100644
--- a/test/sha1test.c
+++ b/test/sha1test.c
@@ -88,7 +88,7 @@ int main(int argc, char *argv[])
     char **P, **R;
     static unsigned char buf[1000];
     char *p, *r;
-    EVP_MD_CTX c;
+    EVP_MD_CTX *c;
     unsigned char md[SHA_DIGEST_LENGTH];
 
 #ifdef CHARSET_EBCDIC
@@ -96,7 +96,7 @@ int main(int argc, char *argv[])
     ebcdic2ascii(test[1], test[1], strlen(test[1]));
 #endif
 
-    EVP_MD_CTX_init(&c);
+    c = EVP_MD_CTX_new();
     P = test;
     R = ret;
     i = 1;
@@ -118,10 +118,10 @@ int main(int argc, char *argv[])
 #ifdef CHARSET_EBCDIC
     ebcdic2ascii(buf, buf, 1000);
 #endif                         /* CHARSET_EBCDIC */
-    EVP_DigestInit_ex(&c, EVP_sha1(), NULL);
+    EVP_DigestInit_ex(c, EVP_sha1(), NULL);
     for (i = 0; i < 1000; i++)
-        EVP_DigestUpdate(&c, buf, 1000);
-    EVP_DigestFinal_ex(&c, md, NULL);
+        EVP_DigestUpdate(c, buf, 1000);
+    EVP_DigestFinal_ex(c, md, NULL);
     p = pt(md);
 
     r = bigret;
@@ -137,7 +137,7 @@ int main(int argc, char *argv[])
         printf("ERROR: %d\n", err);
 #endif
     EXIT(err);
-    EVP_MD_CTX_cleanup(&c);
+    EVP_MD_CTX_free(c);
     return (0);
 }
 
diff --git a/test/sha256t.c b/test/sha256t.c
index 11f3684..2ff9ed2 100644
--- a/test/sha256t.c
+++ b/test/sha256t.c
@@ -56,7 +56,7 @@ int main(int argc, char **argv)
 {
     unsigned char md[SHA256_DIGEST_LENGTH];
     int i;
-    EVP_MD_CTX evp;
+    EVP_MD_CTX *evp;
 
     fprintf(stdout, "Testing SHA-256 ");
 
@@ -80,10 +80,15 @@ int main(int argc, char **argv)
         fprintf(stdout, ".");
     fflush(stdout);
 
-    EVP_MD_CTX_init(&evp);
-    EVP_DigestInit_ex(&evp, EVP_sha256(), NULL);
+    evp = EVP_MD_CTX_new();
+    if (evp == NULL) {
+        fflush(stdout);
+        fprintf(stderr, "\nTEST 3 of 3 failed. (malloc failure)\n");
+        return 1;
+    }
+    EVP_DigestInit_ex(evp, EVP_sha256(), NULL);
     for (i = 0; i < 1000000; i += 288)
-        EVP_DigestUpdate(&evp, "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa"
+        EVP_DigestUpdate(evp, "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa"
                          "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa"
                          "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa"
                          "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa"
@@ -93,8 +98,7 @@ int main(int argc, char **argv)
                          "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa"
                          "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa",
                          (1000000 - i) < 288 ? 1000000 - i : 288);
-    EVP_DigestFinal_ex(&evp, md, NULL);
-    EVP_MD_CTX_cleanup(&evp);
+    EVP_DigestFinal_ex(evp, md, NULL);
 
     if (memcmp(md, app_b3, sizeof(app_b3))) {
         fflush(stdout);
@@ -129,14 +133,14 @@ int main(int argc, char **argv)
         fprintf(stdout, ".");
     fflush(stdout);
 
-    EVP_MD_CTX_init(&evp);
-    EVP_DigestInit_ex(&evp, EVP_sha224(), NULL);
+    EVP_MD_CTX_reset(evp);
+    EVP_DigestInit_ex(evp, EVP_sha224(), NULL);
     for (i = 0; i < 1000000; i += 64)
-        EVP_DigestUpdate(&evp, "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa"
+        EVP_DigestUpdate(evp, "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa"
                          "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa",
                          (1000000 - i) < 64 ? 1000000 - i : 64);
-    EVP_DigestFinal_ex(&evp, md, NULL);
-    EVP_MD_CTX_cleanup(&evp);
+    EVP_DigestFinal_ex(evp, md, NULL);
+    EVP_MD_CTX_free(evp);
 
     if (memcmp(md, addenum_3, sizeof(addenum_3))) {
         fflush(stdout);
diff --git a/test/sha512t.c b/test/sha512t.c
index f60d319..e1f30de 100644
--- a/test/sha512t.c
+++ b/test/sha512t.c
@@ -75,7 +75,7 @@ int main(int argc, char **argv)
 {
     unsigned char md[SHA512_DIGEST_LENGTH];
     int i;
-    EVP_MD_CTX evp;
+    EVP_MD_CTX *evp;
 
 # ifdef OPENSSL_IA32_SSE2
     /*
@@ -113,10 +113,15 @@ int main(int argc, char **argv)
         fprintf(stdout, ".");
     fflush(stdout);
 
-    EVP_MD_CTX_init(&evp);
-    EVP_DigestInit_ex(&evp, EVP_sha512(), NULL);
+    evp = EVP_MD_CTX_new();
+    if (evp == NULL) {
+        fflush(stdout);
+        fprintf(stderr, "\nTEST 3 of 3 failed. (malloc failure)\n");
+        return 1;
+    }
+    EVP_DigestInit_ex(evp, EVP_sha512(), NULL);
     for (i = 0; i < 1000000; i += 288)
-        EVP_DigestUpdate(&evp, "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa"
+        EVP_DigestUpdate(evp, "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa"
                          "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa"
                          "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa"
                          "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa"
@@ -126,8 +131,8 @@ int main(int argc, char **argv)
                          "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa"
                          "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa",
                          (1000000 - i) < 288 ? 1000000 - i : 288);
-    EVP_DigestFinal_ex(&evp, md, NULL);
-    EVP_MD_CTX_cleanup(&evp);
+    EVP_DigestFinal_ex(evp, md, NULL);
+    EVP_MD_CTX_reset(evp);
 
     if (memcmp(md, app_c3, sizeof(app_c3))) {
         fflush(stdout);
@@ -163,14 +168,13 @@ int main(int argc, char **argv)
         fprintf(stdout, ".");
     fflush(stdout);
 
-    EVP_MD_CTX_init(&evp);
-    EVP_DigestInit_ex(&evp, EVP_sha384(), NULL);
+    EVP_DigestInit_ex(evp, EVP_sha384(), NULL);
     for (i = 0; i < 1000000; i += 64)
-        EVP_DigestUpdate(&evp, "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa"
+        EVP_DigestUpdate(evp, "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa"
                          "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa",
                          (1000000 - i) < 64 ? 1000000 - i : 64);
-    EVP_DigestFinal_ex(&evp, md, NULL);
-    EVP_MD_CTX_cleanup(&evp);
+    EVP_DigestFinal_ex(evp, md, NULL);
+    EVP_MD_CTX_free(evp);
 
     if (memcmp(md, app_d3, sizeof(app_d3))) {
         fflush(stdout);
diff --git a/util/libeay.num b/util/libeay.num
index f6bbf06..8b7f296 100755
--- a/util/libeay.num
+++ b/util/libeay.num
@@ -2066,7 +2066,7 @@ KRB5_APREQBODY_new                      2626	NOEXIST::FUNCTION:
 X509V3_EXT_REQ_add_nconf                2627	EXIST::FUNCTION:
 ENGINE_ctrl_cmd_string                  2628	EXIST::FUNCTION:ENGINE
 i2d_OCSP_RESPDATA                       2629	EXIST::FUNCTION:
-EVP_MD_CTX_init                         2630	EXIST::FUNCTION:
+EVP_MD_CTX_reset                        2630	EXIST::FUNCTION:
 EXTENDED_KEY_USAGE_free                 2631	EXIST::FUNCTION:
 PKCS7_ATTR_SIGN_it                      2632	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
 PKCS7_ATTR_SIGN_it                      2632	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
@@ -2162,7 +2162,7 @@ ENGINE_load_builtin_engines             2708	EXIST::FUNCTION:ENGINE
 i2d_OCSP_ONEREQ                         2709	EXIST::FUNCTION:
 OCSP_REQUEST_add_ext                    2710	EXIST::FUNCTION:
 OCSP_RESPBYTES_new                      2711	EXIST::FUNCTION:
-EVP_MD_CTX_create                       2712	EXIST::FUNCTION:
+EVP_MD_CTX_new                          2712	EXIST::FUNCTION:
 OCSP_resp_find_status                   2713	EXIST::FUNCTION:
 X509_ALGOR_it                           2714	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
 X509_ALGOR_it                           2714	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
@@ -2207,7 +2207,7 @@ OBJ_NAME_do_all_sorted                  2743	EXIST::FUNCTION:
 i2d_OCSP_BASICRESP                      2744	EXIST::FUNCTION:
 i2d_OCSP_RESPBYTES                      2745	EXIST::FUNCTION:
 PKCS12_unpack_p7encdata                 2746	EXIST::FUNCTION:
-HMAC_CTX_init                           2747	EXIST::FUNCTION:
+HMAC_CTX_reset                          2747	EXIST::FUNCTION:
 ENGINE_get_digest                       2748	EXIST::FUNCTION:ENGINE
 OCSP_RESPONSE_print                     2749	EXIST::FUNCTION:
 KRB5_TKTBODY_it                         2750	NOEXIST::FUNCTION:
@@ -2256,7 +2256,7 @@ CRYPTO_get_locked_mem_ex_funcs          2781	NOEXIST::FUNCTION:
 CRYPTO_get_locked_mem_ex_functions      2781	NOEXIST::FUNCTION:
 ASN1_TIME_check                         2782	EXIST::FUNCTION:
 UI_get0_user_data                       2783	EXIST::FUNCTION:
-HMAC_CTX_cleanup                        2784	EXIST::FUNCTION:
+HMAC_CTX_cleanup                        2784	NOEXIST::FUNCTION:
 DSA_up_ref                              2785	EXIST::FUNCTION:DSA
 _ossl_odes_ede3_cfb64_encrypt           2786	NOEXIST::FUNCTION:
 _ossl_old_des_ede3_cfb64_encrypt        2786	NOEXIST::FUNCTION:
@@ -2306,7 +2306,7 @@ OCSP_RESPDATA_free                      2818	EXIST::FUNCTION:
 d2i_KRB5_TICKET                         2819	NOEXIST::FUNCTION:
 OTHERNAME_it                            2820	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
 OTHERNAME_it                            2820	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
-EVP_MD_CTX_cleanup                      2821	EXIST::FUNCTION:
+EVP_MD_CTX_cleanup                      2821	NOEXIST::FUNCTION:
 d2i_ASN1_GENERALSTRING                  2822	EXIST::FUNCTION:
 X509_CRL_set_version                    2823	EXIST::FUNCTION:
 BN_mod_sub                              2824	EXIST::FUNCTION:
@@ -2427,7 +2427,7 @@ BASIC_CONSTRAINTS_it                    2922	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIA
 BASIC_CONSTRAINTS_it                    2922	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
 BN_mod_add_quick                        2923	EXIST::FUNCTION:
 EC_POINT_new                            2924	EXIST::FUNCTION:EC
-EVP_MD_CTX_destroy                      2925	EXIST::FUNCTION:
+EVP_MD_CTX_free                         2925	EXIST::FUNCTION:
 OCSP_RESPBYTES_free                     2926	EXIST::FUNCTION:
 EVP_aes_128_cbc                         2927	EXIST::FUNCTION:AES
 OCSP_SINGLERESP_get1_ext_d2i            2928	EXIST::FUNCTION:
@@ -4666,3 +4666,33 @@ ASYNC_init                              5025	EXIST::FUNCTION:
 EVP_MD_CTX_ctrl                         5026	EXIST::FUNCTION:
 EVP_md5_sha1                            5027	EXIST::FUNCTION:MD5
 CRYPTO_free_ex_index                    5028	EXIST::FUNCTION:
+EVP_MD_meth_set_copy                    5029	EXIST::FUNCTION:
+EVP_MD_meth_set_flags                   5030	EXIST::FUNCTION:
+EVP_MD_meth_set_input_blocksize         5031	EXIST::FUNCTION:
+EVP_MD_meth_get_update                  5032	EXIST::FUNCTION:
+EVP_MD_meth_get_input_blocksize         5033	EXIST::FUNCTION:
+EVP_MD_CTX_pkey_ctx                     5034	EXIST::FUNCTION:
+EVP_MD_meth_set_ctrl                    5035	EXIST::FUNCTION:
+EVP_MD_meth_get_init                    5036	EXIST::FUNCTION:
+EVP_MD_meth_new                         5037	EXIST::FUNCTION:
+EVP_MD_meth_get_ctrl                    5038	EXIST::FUNCTION:
+EVP_MD_CTX_update_fn                    5039	EXIST::FUNCTION:
+EVP_MD_meth_set_update                  5040	EXIST::FUNCTION:
+EVP_MD_meth_get_final                   5041	EXIST::FUNCTION:
+EVP_MD_CTX_md_data                      5042	EXIST::FUNCTION:
+EVP_MD_meth_set_app_datasize            5043	EXIST::FUNCTION:
+EVP_MD_meth_set_result_size             5044	EXIST::FUNCTION:
+EVP_MD_meth_set_final                   5045	EXIST::FUNCTION:
+EVP_MD_meth_get_result_size             5046	EXIST::FUNCTION:
+EVP_MD_meth_get_flags                   5047	EXIST::FUNCTION:
+EVP_MD_meth_get_app_datasize            5048	EXIST::FUNCTION:
+EVP_MD_meth_free                        5049	EXIST::FUNCTION:
+EVP_MD_meth_set_cleanup                 5050	EXIST::FUNCTION:
+EVP_MD_meth_get_cleanup                 5051	EXIST::FUNCTION:
+EVP_MD_meth_set_init                    5052	EXIST::FUNCTION:
+EVP_MD_meth_get_copy                    5053	EXIST::FUNCTION:
+EVP_MD_CTX_set_update_fn                5054	EXIST::FUNCTION:
+EVP_MD_meth_dup                         5055	EXIST::FUNCTION:
+HMAC_size                               5056	EXIST::FUNCTION:
+HMAC_CTX_new                            5057	EXIST::FUNCTION:
+HMAC_CTX_free                           5058	EXIST::FUNCTION:


More information about the openssl-commits mailing list