Index: trunk/src/VBox/Runtime/Makefile.kmk
===================================================================
--- trunk/src/VBox/Runtime/Makefile.kmk	(revision 74312)
+++ trunk/src/VBox/Runtime/Makefile.kmk	(revision 74313)
@@ -366,4 +366,5 @@
 	common/checksum/sha512t224str.cpp \
 	common/checksum/sha512t256str.cpp \
+	common/crypto/cipher-openssl.cpp \
 	common/crypto/digest-core.cpp \
 	common/crypto/digest-builtin.cpp \
Index: trunk/src/VBox/Runtime/VBox/VBoxRTImp.def
===================================================================
--- trunk/src/VBox/Runtime/VBox/VBoxRTImp.def	(revision 74312)
+++ trunk/src/VBox/Runtime/VBox/VBoxRTImp.def	(revision 74313)
@@ -776,4 +776,12 @@
     RTCritSectTryEnter
     RTCritSectTryEnterDebug
+    RTCrCipherDecrypt
+    RTCrCipherEncrypt
+    RTCrCipherGetBlockSize
+    RTCrCipherGetInitializationVectorLength
+    RTCrCipherGetKeyVectorLength
+    RTCrCipherOpenByType
+    RTCrCipherRetain
+    RTCrCipherRelease
     RTCrDigestClone
     RTCrDigestCreate
@@ -814,6 +822,5 @@
     RTCrKeyQueryRsaModulus
     RTCrKeyQueryRsaPrivateExponent
-    RTCrRc4
-    RTCrRc4SetKey
+    RTCrPkcs5Pbkdf2Hmac
     RTCrPkixGetCiperOidFromSignatureAlgorithm
     RTCrPkixPubKeySignDigest
@@ -830,4 +837,7 @@
     RTCrPkixSignatureVerifyBitString
     RTCrPkixSignatureVerifyOctetString
+    RTCrRandBytes
+    RTCrRc4
+    RTCrRc4SetKey
     RTCrSslCreate
     RTCrSslCreateSessionForNativeSocket
Index: trunk/src/VBox/Runtime/common/crypto/cipher-openssl.cpp
===================================================================
--- trunk/src/VBox/Runtime/common/crypto/cipher-openssl.cpp	(revision 74313)
+++ trunk/src/VBox/Runtime/common/crypto/cipher-openssl.cpp	(revision 74313)
@@ -0,0 +1,348 @@
+/* $Id$ */
+/** @file
+ * IPRT - Crypto - Symmetric Cipher using OpenSSL.
+ */
+
+/*
+ * Copyright (C) 2018 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#ifdef IPRT_WITH_OPENSSL
+# include "internal/iprt.h"
+# include <iprt/crypto/cipher.h>
+
+# include <iprt/asm.h>
+# include <iprt/assert.h>
+# include <iprt/err.h>
+# include <iprt/mem.h>
+# include <iprt/string.h>
+
+# include "internal/iprt-openssl.h"
+# include "openssl/evp.h"
+
+# include "internal/magics.h"
+
+
+/*********************************************************************************************************************************
+*   Structures and Typedefs                                                                                                      *
+*********************************************************************************************************************************/
+/**
+ * OpenSSL cipher instance data.
+ */
+typedef struct RTCRCIPHERINT
+{
+    /** Magic value (RTCRCIPHERINT_MAGIC). */
+    uint32_t            u32Magic;
+    /** Reference count. */
+    uint32_t volatile   cRefs;
+    /** The cihper. */
+    const EVP_CIPHER   *pCipher;
+    /** The IPRT cipher type, if we know it. */
+    RTCRCIPHERTYPE      enmType;
+} RTCRCIPHERINT;
+
+
+RTDECL(int) RTCrCipherOpenByType(PRTCRCIPHER phCipher, RTCRCIPHERTYPE enmType, uint32_t fFlags)
+{
+    AssertPtrReturn(phCipher, VERR_INVALID_POINTER);
+    *phCipher = NIL_RTCRCIPHER;
+    AssertReturn(!fFlags, VERR_INVALID_FLAGS);
+
+    /*
+     * Translate the IPRT cipher type to EVP cipher.
+     */
+    const EVP_CIPHER *pCipher = NULL;
+    switch (enmType)
+    {
+        case RTCRCIPHERTYPE_XTS_AES_128:
+            pCipher = EVP_aes_128_xts();
+            break;
+        case RTCRCIPHERTYPE_XTS_AES_256:
+            pCipher = EVP_aes_256_xts();
+            break;
+
+        /* no default! */
+        case RTCRCIPHERTYPE_INVALID:
+        case RTCRCIPHERTYPE_END:
+        case RTCRCIPHERTYPE_32BIT_HACK:
+            AssertFailedReturn(VERR_INVALID_PARAMETER);
+    }
+    AssertReturn(pCipher, VERR_CR_CIPHER_NOT_SUPPORTED);
+
+    /*
+     * Create the instance.
+     */
+    RTCRCIPHERINT *pThis = (RTCRCIPHERINT *)RTMemAllocZ(sizeof(*pThis));
+    if (pThis)
+    {
+        pThis->u32Magic = RTCRCIPHERINT_MAGIC;
+        pThis->cRefs    = 1;
+        pThis->pCipher  = pCipher;
+        pThis->enmType  = enmType;
+        *phCipher = pThis;
+        return VINF_SUCCESS;
+    }
+    return VERR_NO_MEMORY;
+}
+
+
+RTDECL(uint32_t) RTCrCipherRetain(RTCRCIPHER hCipher)
+{
+    RTCRCIPHERINT *pThis = hCipher;
+    AssertPtrReturn(pThis, UINT32_MAX);
+    AssertReturn(pThis->u32Magic == RTCRCIPHERINT_MAGIC, UINT32_MAX);
+
+    uint32_t cRefs = ASMAtomicIncU32(&pThis->cRefs);
+    Assert(cRefs > 1 && cRefs < 1024);
+    return cRefs;
+}
+
+
+/**
+ * Destroys the cipher instance.
+ */
+static uint32_t rtCrCipherDestroy(RTCRCIPHER pThis)
+{
+    pThis->u32Magic= ~RTCRCIPHERINT_MAGIC;
+    pThis->pCipher = NULL;
+    RTMemFree(pThis);
+    return 0;
+}
+
+
+RTDECL(uint32_t) RTCrCipherRelease(RTCRCIPHER hCipher)
+{
+    RTCRCIPHERINT *pThis = hCipher;
+    if (pThis == NIL_RTCRCIPHER)
+        return 0;
+    AssertPtrReturn(pThis, UINT32_MAX);
+    AssertReturn(pThis->u32Magic == RTCRCIPHERINT_MAGIC, UINT32_MAX);
+
+    uint32_t cRefs = ASMAtomicDecU32(&pThis->cRefs);
+    Assert(cRefs < 1024);
+    if (!cRefs == 0)
+        return rtCrCipherDestroy(pThis);
+    return cRefs;
+}
+
+
+RTDECL(uint32_t) RTCrCipherGetKeyLength(RTCRCIPHER hCipher)
+{
+    RTCRCIPHERINT *pThis = hCipher;
+    AssertPtrReturn(pThis, 0);
+    AssertReturn(pThis->u32Magic == RTCRCIPHERINT_MAGIC, 0);
+
+    return EVP_CIPHER_key_length(pThis->pCipher);
+}
+
+
+RTDECL(uint32_t) RTCrCipherGetInitialVectorLength(RTCRCIPHER hCipher)
+{
+    RTCRCIPHERINT *pThis = hCipher;
+    AssertPtrReturn(pThis, 0);
+    AssertReturn(pThis->u32Magic == RTCRCIPHERINT_MAGIC, 0);
+
+    return EVP_CIPHER_iv_length(pThis->pCipher);
+}
+
+
+RTDECL(uint32_t) RTCrCipherGetBlockSize(RTCRCIPHER hCipher)
+{
+    RTCRCIPHERINT *pThis = hCipher;
+    AssertPtrReturn(pThis, 0);
+    AssertReturn(pThis->u32Magic == RTCRCIPHERINT_MAGIC, 0);
+
+    return EVP_CIPHER_block_size(pThis->pCipher);
+}
+
+
+RTDECL(int) RTCrCipherEncrypt(RTCRCIPHER hCipher, void const *pvKey, size_t cbKey,
+                              void const *pvInitVector, size_t cbInitVector,
+                              void const *pvPlainText, size_t cbPlainText,
+                              void *pvEncrypted, size_t cbEncrypted, size_t *pcbEncrypted)
+{
+    /*
+     * Validate input.
+     */
+    RTCRCIPHERINT *pThis = hCipher;
+    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+    AssertReturn(pThis->u32Magic == RTCRCIPHERINT_MAGIC, VERR_INVALID_HANDLE);
+    AssertMsgReturn((ssize_t)cbKey != EVP_CIPHER_key_length(pThis->pCipher),
+                    ("%zu, expected %d\n", cbKey, EVP_CIPHER_key_length(pThis->pCipher)),
+                    VERR_CR_CIPHER_INVALID_KEY_LENGTH);
+    AssertMsgReturn((ssize_t)cbInitVector != EVP_CIPHER_iv_length(pThis->pCipher),
+                    ("%zu, expected %d\n", cbInitVector, EVP_CIPHER_iv_length(pThis->pCipher)),
+                    VERR_CR_CIPHER_INVALID_INITIALIZATION_VECTOR_LENGTH);
+    AssertReturn(cbPlainText > 0, VERR_NO_DATA);
+
+    Assert(EVP_CIPHER_block_size(pThis->pCipher) <= 1); /** @todo more complicated ciphers later */
+    size_t const cbNeeded = cbPlainText;
+    if (pcbEncrypted)
+    {
+        *pcbEncrypted = cbNeeded;
+        AssertReturn(cbEncrypted >= cbNeeded, VERR_BUFFER_OVERFLOW);
+    }
+    else
+        AssertReturn(cbEncrypted == cbNeeded, VERR_INVALID_PARAMETER);
+    AssertReturn((size_t)(int)cbPlainText == cbPlainText && (int)cbPlainText > 0, VERR_OUT_OF_RANGE);
+
+    /*
+     * Allocate and initialize the cipher context.
+     */
+    int rc = VERR_NO_MEMORY;
+# if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
+    EVP_CIPHER_CTX *pCipherCtx = EVP_CIPHER_CTX_new();
+    if (pCipherCtx)
+# else
+    EVP_CIPHER_CTX  CipherCtx;
+    EVP_CIPHER_CTX *pCipherCtx = &CipherCtx;
+    RT_ZERO(CipherCtx);
+# endif
+    {
+        int rcOssl = EVP_EncryptInit(pCipherCtx, pThis->pCipher, (unsigned char const *)pvKey,
+                                     (unsigned char const *)pvInitVector);
+        if (rcOssl > 0)
+        {
+            /*
+             * Do the encryption.
+             */
+            int cbEncrypted = 0;
+            rcOssl = EVP_EncryptUpdate(pCipherCtx, (unsigned char *)pvEncrypted, &cbEncrypted,
+                                       (unsigned char const *)pvPlainText, (int)cbPlainText);
+            if (rcOssl > 0)
+            {
+                Assert(cbEncrypted <= (ssize_t)cbNeeded);
+                int cbEncryptedFinal = 0;
+                rcOssl = EVP_DecryptFinal(pCipherCtx, (unsigned char *)pvEncrypted + cbEncrypted, &cbEncryptedFinal);
+                if (rcOssl > 0)
+                {
+                    Assert(cbEncryptedFinal + cbEncrypted == (ssize_t)cbNeeded);
+                    if (pcbEncrypted)
+                        *pcbEncrypted = cbEncryptedFinal + cbEncrypted;
+                    rc = VINF_SUCCESS;
+                }
+                else
+                    rc = VERR_CR_CIPHER_OSSL_ENCRYPT_FINAL_FAILED;
+            }
+            else
+                rc = VERR_CR_CIPHER_OSSL_ENCRYPT_UPDATE_FAILED;
+        }
+        else
+            rc = VERR_CR_CIPHER_OSSL_ENCRYPT_INIT_FAILED;
+
+# if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
+        EVP_CIPHER_CTX_free(pCipherCtx);
+# else
+        EVP_CIPHER_CTX_cleanup(&CipherCtx);
+# endif
+    }
+    return rc;
+}
+
+
+RTDECL(int) RTCrCipherDecrypt(RTCRCIPHER hCipher, void const *pvKey, size_t cbKey,
+                              void const *pvInitVector, size_t cbInitVector,
+                              void const *pvEncrypted, size_t cbEncrypted,
+                              void *pvPlainText, size_t cbPlainText, size_t *pcbPlainText)
+{
+    /*
+     * Validate input.
+     */
+    RTCRCIPHERINT *pThis = hCipher;
+    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+    AssertReturn(pThis->u32Magic == RTCRCIPHERINT_MAGIC, VERR_INVALID_HANDLE);
+    AssertMsgReturn((ssize_t)cbKey != EVP_CIPHER_key_length(pThis->pCipher),
+                    ("%zu, expected %d\n", cbKey, EVP_CIPHER_key_length(pThis->pCipher)),
+                    VERR_CR_CIPHER_INVALID_KEY_LENGTH);
+    AssertMsgReturn((ssize_t)cbInitVector != EVP_CIPHER_iv_length(pThis->pCipher),
+                    ("%zu, expected %d\n", cbInitVector, EVP_CIPHER_iv_length(pThis->pCipher)),
+                    VERR_CR_CIPHER_INVALID_INITIALIZATION_VECTOR_LENGTH);
+    AssertReturn(cbPlainText > 0, VERR_NO_DATA);
+
+    Assert(EVP_CIPHER_block_size(pThis->pCipher) <= 1); /** @todo more complicated ciphers later */
+    size_t const cbNeeded = cbEncrypted;
+    if (pcbPlainText)
+    {
+        *pcbPlainText = cbNeeded;
+        AssertReturn(cbPlainText >= cbNeeded, VERR_BUFFER_OVERFLOW);
+    }
+    else
+        AssertReturn(cbPlainText == cbNeeded, VERR_INVALID_PARAMETER);
+    AssertReturn((size_t)(int)cbEncrypted == cbEncrypted && (int)cbEncrypted > 0, VERR_OUT_OF_RANGE);
+
+    /*
+     * Allocate and initialize the cipher context.
+     */
+    int rc = VERR_NO_MEMORY;
+# if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
+    EVP_CIPHER_CTX *pCipherCtx = EVP_CIPHER_CTX_new();
+    if (pCipherCtx)
+# else
+    EVP_CIPHER_CTX  CipherCtx;
+    EVP_CIPHER_CTX *pCipherCtx = &CipherCtx;
+    RT_ZERO(CipherCtx);
+# endif
+    {
+        int rcOssl = EVP_DecryptInit(pCipherCtx, pThis->pCipher, (unsigned char const *)pvKey,
+                                     (unsigned char const *)pvInitVector);
+        if (rcOssl > 0)
+        {
+            /*
+             * Do the decryption.
+             */
+            int cbDecrypted = 0;
+            rcOssl = EVP_DecryptUpdate(pCipherCtx, (unsigned char *)pvPlainText, &cbDecrypted,
+                                       (unsigned char const *)pvEncrypted, (int)cbEncrypted);
+            if (rcOssl > 0)
+            {
+                Assert(cbDecrypted <= (ssize_t)cbNeeded);
+                int cbDecryptedFinal = 0;
+                rcOssl = EVP_DecryptFinal(pCipherCtx, (unsigned char *)pvPlainText + cbDecrypted, &cbDecryptedFinal);
+                if (rcOssl > 0)
+                {
+                    Assert(cbDecryptedFinal + cbDecrypted == (ssize_t)cbNeeded);
+                    if (pcbPlainText)
+                        *pcbPlainText = cbDecryptedFinal + cbDecrypted;
+                    rc = VINF_SUCCESS;
+                }
+                else
+                    rc = VERR_CR_CIPHER_OSSL_DECRYPT_FINAL_FAILED;
+            }
+            else
+                rc = VERR_CR_CIPHER_OSSL_DECRYPT_UPDATE_FAILED;
+        }
+        else
+            rc = VERR_CR_CIPHER_OSSL_DECRYPT_INIT_FAILED;
+
+# if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
+        EVP_CIPHER_CTX_free(pCipherCtx);
+# else
+        EVP_CIPHER_CTX_cleanup(&CipherCtx);
+# endif
+    }
+    return rc;
+}
+
+#endif /* IPRT_WITH_OPENSSL */
+
Index: trunk/src/VBox/Runtime/include/internal/magics.h
===================================================================
--- trunk/src/VBox/Runtime/include/internal/magics.h	(revision 74312)
+++ trunk/src/VBox/Runtime/include/internal/magics.h	(revision 74313)
@@ -35,4 +35,6 @@
 /** Magic number for RTAIOMGRINTFILE::u32Magic. (Ephraim Kishon) */
 #define RTAIOMGRFILE_MAGIC              UINT32_C(0x19240823)
+/** Magic number for RTCRCIPHERINT::u32Magic. (Michael Wolff) */
+#define RTCRCIPHERINT_MAGIC             UINT32_C(0x19530827)
 /** Magic value for RTCRKEYINT::u32Magic. (Ronald Linn Rivest) */
 #define RTCRKEYINT_MAGIC                UINT32_C(0x19470506)
