Index: /trunk/include/iprt/crypto/digest.h
===================================================================
--- /trunk/include/iprt/crypto/digest.h	(revision 61890)
+++ /trunk/include/iprt/crypto/digest.h	(revision 61891)
@@ -61,4 +61,16 @@
 
     /**
+     * Allocates the digest data.
+     */
+    DECLCALLBACKMEMBER(void *, pfnNew)(void);
+    
+    /**
+     * Frees the digest data.
+     *
+     * @param   pvState     The opaque message digest state.
+     */
+    DECLCALLBACKMEMBER(void, pfnFree)(void *pvState);
+
+    /**
      * Updates the digest with more data.
      *
Index: /trunk/src/VBox/Runtime/common/crypto/digest-builtin.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/crypto/digest-builtin.cpp	(revision 61890)
+++ /trunk/src/VBox/Runtime/common/crypto/digest-builtin.cpp	(revision 61891)
@@ -87,4 +87,6 @@
     sizeof(RTMD2CONTEXT),
     0,
+    NULL,
+    NULL,
     rtCrDigestMd2_Update,
     rtCrDigestMd2_Final,
@@ -139,4 +141,6 @@
     sizeof(RTMD5CONTEXT),
     0,
+    NULL,
+    NULL,
     rtCrDigestMd5_Update,
     rtCrDigestMd5_Final,
@@ -191,4 +195,6 @@
     sizeof(RTSHA1CONTEXT),
     0,
+    NULL,
+    NULL,
     rtCrDigestSha1_Update,
     rtCrDigestSha1_Final,
@@ -242,4 +248,6 @@
     sizeof(RTSHA256CONTEXT),
     0,
+    NULL,
+    NULL,
     rtCrDigestSha256_Update,
     rtCrDigestSha256_Final,
@@ -293,4 +301,6 @@
     sizeof(RTSHA512CONTEXT),
     0,
+    NULL,
+    NULL,
     rtCrDigestSha512_Update,
     rtCrDigestSha512_Final,
@@ -344,4 +354,6 @@
     sizeof(RTSHA224CONTEXT),
     0,
+    NULL,
+    NULL,
     rtCrDigestSha224_Update,
     rtCrDigestSha224_Final,
@@ -395,4 +407,6 @@
     sizeof(RTSHA384CONTEXT),
     0,
+    NULL,
+    NULL,
     rtCrDigestSha384_Update,
     rtCrDigestSha384_Final,
@@ -446,4 +460,6 @@
     sizeof(RTSHA512T224CONTEXT),
     0,
+    NULL,
+    NULL,
     rtCrDigestSha512t224_Update,
     rtCrDigestSha512t224_Final,
@@ -498,4 +514,6 @@
     sizeof(RTSHA512T256CONTEXT),
     0,
+    NULL,
+    NULL,
     rtCrDigestSha512t256_Update,
     rtCrDigestSha512t256_Final,
@@ -534,4 +552,18 @@
  * OpenSSL EVP.
  */
+    
+# if OPENSSL_VERSION_NUMBER >= 0x10100000
+/** @impl_interface_method{RTCRDIGESTDESC::pfnNew} */
+static DECLCALLBACK(void*) rtCrDigestOsslEvp_New(void)
+{
+    return EVP_MD_CTX_new();
+}
+
+static DECLCALLBACK(void) rtCrDigestOsslEvp_Free(void *pvState)
+{
+    EVP_MD_CTX_free((EVP_MD_CTX*)pvState);
+}
+
+# endif
 
 /** @impl_interface_method{RTCRDIGESTDESC::pfnUpdate} */
@@ -540,5 +572,4 @@
     EVP_DigestUpdate((EVP_MD_CTX *)pvState, pvData, cbData);
 }
-
 
 /** @impl_interface_method{RTCRDIGESTDESC::pfnFinal} */
@@ -558,5 +589,9 @@
     {
         pEvpType = EVP_MD_CTX_md(pThis);
+# if OPENSSL_VERSION_NUMBER >= 0x10100000
+        EVP_MD_CTX_reset(pThis);
+# else
         EVP_MD_CTX_cleanup(pThis);
+# endif
     }
 
@@ -573,5 +608,9 @@
 {
     EVP_MD_CTX *pThis = (EVP_MD_CTX *)pvState;
+# if OPENSSL_VERSION_NUMBER >= 0x10100000
+    EVP_MD_CTX_reset(pThis);
+# else
     EVP_MD_CTX_cleanup(pThis);
+# endif
 }
 
@@ -614,6 +653,13 @@
     RTDIGESTTYPE_UNKNOWN,
     EVP_MAX_MD_SIZE,
-    sizeof(EVP_MD_CTX),
-    0,
+    0,
+    0,
+# if OPENSSL_VERSION_NUMBER >= 0x10100000
+    rtCrDigestOsslEvp_New,
+    rtCrDigestOsslEvp_Free,
+# else
+    NULL,
+    NULL,
+# endif
     rtCrDigestOsslEvp_Update,
     rtCrDigestOsslEvp_Final,
Index: /trunk/src/VBox/Runtime/common/crypto/digest-core.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/crypto/digest-core.cpp	(revision 61890)
+++ /trunk/src/VBox/Runtime/common/crypto/digest-core.cpp	(revision 61891)
@@ -60,7 +60,12 @@
     /** The number of bytes consumed. */
     uint64_t            cbConsumed;
+    /** Pointer to the data specific to the message digest algorithm. Points
+     * either to &abState[0] or to memory allocated with pDesc->pfnNew. */
+    void               *pvState;
     /** Opaque data specific to the message digest algorithm, size given by
-     * RTCRDIGESTDESC::cbState.  This is followed by space for the final hash at
-     * offHash with size RTCRDIGESTDESC::cbHash. */
+     * RTCRDIGESTDESC::cbState.  This is followed by space for the final hash
+     * at offHash with size RTCRDIGESTDESC::cbHash.  The data specific to the
+     * message digest algorithm can also be 0. In this case, pDesc->pfnNew()
+     * and pDesc->pfnFree() must not be NULL. */
     uint8_t             abState[1];
 } RTCRDIGESTINT;
@@ -89,20 +94,33 @@
 
     int rc = VINF_SUCCESS;
-    uint32_t offHash = RT_ALIGN_32(pDesc->cbState, 8);
+    uint32_t const offHash = RT_ALIGN_32(pDesc->cbState, 8);
+    AssertReturn(pDesc->pfnNew || offHash, VERR_INVALID_PARAMETER);
+    AssertReturn(!pDesc->pfnNew || (pDesc->pfnFree && pDesc->pfnInit && pDesc->pfnClone), VERR_INVALID_PARAMETER);
     PRTCRDIGESTINT pThis = (PRTCRDIGESTINT)RTMemAllocZ(RT_OFFSETOF(RTCRDIGESTINT, abState[offHash + pDesc->cbHash]));
     if (pThis)
     {
-        pThis->u32Magic = RTCRDIGESTINT_MAGIC;
-        pThis->cRefs    = 1;
-        pThis->offHash  = offHash;
-        pThis->pDesc    = pDesc;
-        pThis->uState   = RTCRDIGEST_STATE_READY;
-        if (pDesc->pfnInit)
-            rc = pDesc->pfnInit(pThis->abState, pvOpaque, false /*fReInit*/);
-        if (RT_SUCCESS(rc))
+        if (pDesc->pfnNew)
+            pThis->pvState = pDesc->pfnNew();
+        else
+            pThis->pvState = &pThis->abState[0];
+        if (pThis->pvState)
         {
-            *phDigest = pThis;
-            return VINF_SUCCESS;
+            pThis->u32Magic = RTCRDIGESTINT_MAGIC;
+            pThis->cRefs    = 1;
+            pThis->offHash  = offHash;
+            pThis->pDesc    = pDesc;
+            pThis->uState   = RTCRDIGEST_STATE_READY;
+            if (pDesc->pfnInit)
+                rc = pDesc->pfnInit(pThis->pvState, pvOpaque, false /*fReInit*/);
+            if (RT_SUCCESS(rc))
+            {
+                *phDigest = pThis;
+                return VINF_SUCCESS;
+            }
+            if (pDesc->pfnFree)
+                pDesc->pfnFree(pThis->pvState);
         }
+        else
+            rc = VERR_NO_MEMORY;
         pThis->u32Magic = 0;
         RTMemFree(pThis);
@@ -125,20 +143,34 @@
     if (pThis)
     {
-        pThis->u32Magic = RTCRDIGESTINT_MAGIC;
-        pThis->cRefs    = 1;
-        pThis->offHash  = offHash;
-        pThis->pDesc    = hSrc->pDesc;
-        if (hSrc->pDesc->pfnClone)
-            rc = hSrc->pDesc->pfnClone(pThis->abState, hSrc->abState);
-        else
-            memcpy(pThis->abState, hSrc->abState, offHash);
-        memcpy(&pThis->abState[offHash], &hSrc->abState[offHash], hSrc->pDesc->cbHash);
-        pThis->uState = hSrc->uState;
-
-        if (RT_SUCCESS(rc))
+        if (hSrc->pDesc->pfnNew)
+            pThis->pvState = hSrc->pDesc->pfnNew();
+        else
+            pThis->pvState = &pThis->abState[0];
+        if (pThis->pvState)
         {
-            *phDigest = pThis;
-            return VINF_SUCCESS;
+            pThis->u32Magic = RTCRDIGESTINT_MAGIC;
+            pThis->cRefs    = 1;
+            pThis->offHash  = offHash;
+            pThis->pDesc    = hSrc->pDesc;
+            if (hSrc->pDesc->pfnClone)
+                rc = hSrc->pDesc->pfnClone(pThis->pvState, hSrc->pvState);
+            else
+            {
+                Assert(!hSrc->pDesc->pfnNew);
+                memcpy(pThis->pvState, hSrc->pvState, offHash);
+            }
+            memcpy(&pThis->abState[offHash], &hSrc->abState[offHash], hSrc->pDesc->cbHash);
+            pThis->uState = hSrc->uState;
+
+            if (RT_SUCCESS(rc))
+            {
+                *phDigest = pThis;
+                return VINF_SUCCESS;
+            }
+            if (hSrc->pDesc->pfnFree)
+                hSrc->pDesc->pfnFree(pThis->pvState);
         }
+        else
+            rc = VERR_NO_MEMORY;
         pThis->u32Magic = 0;
         RTMemFree(pThis);
@@ -162,5 +194,5 @@
     if (pThis->pDesc->pfnInit)
     {
-        rc = pThis->pDesc->pfnInit(pThis->abState, NULL, true /*fReInit*/);
+        rc = pThis->pDesc->pfnInit(pThis->pvState, NULL, true /*fReInit*/);
         if (RT_FAILURE(rc))
             pThis->uState = RTCRDIGEST_STATE_BUSTED;
@@ -168,5 +200,8 @@
     }
     else
-        RT_BZERO(pThis->abState, pThis->offHash + pThis->pDesc->cbHash);
+    {
+        Assert(!pThis->pDesc->pfnNew);
+        RT_BZERO(pThis->pvState, pThis->offHash + pThis->pDesc->cbHash);
+    }
     return rc;
 }
@@ -198,5 +233,7 @@
         pThis->u32Magic = ~RTCRDIGESTINT_MAGIC;
         if (pThis->pDesc->pfnDelete)
-            pThis->pDesc->pfnDelete(pThis->abState);
+            pThis->pDesc->pfnDelete(pThis->pvState);
+        if (pThis->pDesc->pfnFree)
+            pThis->pDesc->pfnFree(pThis->pvState);
         RTMemFree(pThis);
     }
@@ -213,5 +250,5 @@
     AssertReturn(pThis->uState == RTCRDIGEST_STATE_READY, VERR_INVALID_STATE);
 
-    pThis->pDesc->pfnUpdate(pThis->abState, pvData, cbData);
+    pThis->pDesc->pfnUpdate(pThis->pvState, pvData, cbData);
     pThis->cbConsumed += cbData;
     return VINF_SUCCESS;
@@ -232,5 +269,5 @@
     if (pThis->uState == RTCRDIGEST_STATE_READY)
     {
-        pThis->pDesc->pfnFinal(pThis->abState, &pThis->abState[pThis->offHash]);
+        pThis->pDesc->pfnFinal(pThis->pvState, &pThis->abState[pThis->offHash]);
         pThis->uState = RTCRDIGEST_STATE_FINAL;
     }
@@ -245,5 +282,5 @@
         uint32_t cbNeeded = pThis->pDesc->cbHash;
         if (pThis->pDesc->pfnGetHashSize)
-            cbNeeded = pThis->pDesc->pfnGetHashSize(pThis->abState);
+            cbNeeded = pThis->pDesc->pfnGetHashSize(pThis->pvState);
         Assert(cbNeeded > 0);
 
@@ -300,5 +337,5 @@
     if (pThis->pDesc->pfnGetHashSize)
     {
-        uint32_t cbHash = pThis->pDesc->pfnGetHashSize(pThis->abState);
+        uint32_t cbHash = pThis->pDesc->pfnGetHashSize(pThis->pvState);
         Assert(cbHash <= pThis->pDesc->cbHash);
         return cbHash;
@@ -334,5 +371,5 @@
     RTDIGESTTYPE enmType = pThis->pDesc->enmType;
     if (pThis->pDesc->pfnGetDigestType)
-        enmType = pThis->pDesc->pfnGetDigestType(pThis->abState);
+        enmType = pThis->pDesc->pfnGetDigestType(pThis->pvState);
     return enmType;
 }
