Revert "Fix AES GCM IV setting in KeyProvider"
[platform/core/security/key-manager.git] / src / manager / service / key-provider.cpp
index e89af16..cf15ed8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2014 - 2019 Samsung Electronics Co., Ltd All Rights Reserved
+ *  Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
  *  limitations under the License
  */
 
-#include <exception.h>
+#include <array>
+
+#include <openssl/rand.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/sha.h>
+
 #include <key-provider.h>
-#include <dpl/log/log.h>
 #include <ckm/ckm-zero-memory.h>
+#include <utils.h>
 #include <string.h>
 
-#include <array>
-#include <memory>
-
+#include <crypto-backend.h>
+#ifdef SE_BACKEND_ENABLED
+#include <se-backend/internals.h>
+#endif
 using namespace CKM;
 
 namespace {
 
+constexpr int PBKDF2_ITERATIONS = 4096;
+constexpr uint32_t KEYCOMPONENT_VERSION = 2;
+constexpr int OPENSSL_ENGINE_ERROR = -4;
+
 template<typename T>
 RawBuffer toRawBuffer(const T &data)
 {
@@ -47,8 +58,6 @@ RawBuffer toRawBuffer(T *)
        return RawBuffer();
 }
 
-typedef std::unique_ptr<EVP_CIPHER_CTX, decltype(&EVP_CIPHER_CTX_free)> CipherCtxPtr;
-
 int encryptAes256Gcm(const unsigned char *plaintext,
                      int plaintext_len, const unsigned char *key, const unsigned char *iv,
                      unsigned char *ciphertext, unsigned char *tag)
@@ -56,7 +65,7 @@ int encryptAes256Gcm(const unsigned char *plaintext,
        int len;
        int ciphertext_len = 0;
 
-       CipherCtxPtr ctx(EVP_CIPHER_CTX_new(), EVP_CIPHER_CTX_free);
+       auto ctx = uptr<EVP_CIPHER_CTX_free>(EVP_CIPHER_CTX_new());
        if (!ctx)
                return OPENSSL_ENGINE_ERROR;
 
@@ -93,7 +102,7 @@ int decryptAes256Gcm(const unsigned char *ciphertext,
        int plaintext_len;
        int ret;
 
-       CipherCtxPtr ctx(EVP_CIPHER_CTX_new(), EVP_CIPHER_CTX_free);
+       auto ctx = uptr<EVP_CIPHER_CTX_free>(EVP_CIPHER_CTX_new());
        if (!ctx)
                return OPENSSL_ENGINE_ERROR;
 
@@ -127,17 +136,13 @@ int decryptAes256Gcm(const unsigned char *ciphertext,
 
 typedef std::array<uint8_t, MAX_KEY_SIZE> KeyData;
 
-// derives a key used for DomainKEK encryption (aka PKEK1) from random salt & user password
-KeyData makePKEK1(const KeyComponentsInfo& keyInfo, const Password &password)
+KeyData PBKDF(const std::string& pass, const unsigned char *salt, int saltlen)
 {
-       std::string concatPasswordClient(password.c_str());
-       concatPasswordClient += std::string(keyInfo.client);
-
        KeyData key;
-       if (!PKCS5_PBKDF2_HMAC_SHA1(concatPasswordClient.c_str(),
-                                   concatPasswordClient.size(),
-                                   keyInfo.salt,
-                                   MAX_SALT_SIZE,
+       if (!PKCS5_PBKDF2_HMAC_SHA1(pass.c_str(),
+                                   pass.size(),
+                                   salt,
+                                   saltlen,
                                    PBKDF2_ITERATIONS,
                                    key.size(),
                                    key.data())) {
@@ -146,61 +151,78 @@ KeyData makePKEK1(const KeyComponentsInfo& keyInfo, const Password &password)
        return key;
 }
 
+// derives a key used for DomainKEK encryption (aka PKEK1) from random salt & user password
+KeyData makePKEK1(const DomainKEKInfo& domainKEKInfo, const Password &password)
+{
+       std::string concatPasswordClient(password.c_str());
+       concatPasswordClient += std::string(domainKEKInfo.client);
+
+       if (domainKEKInfo.version != KEYCOMPONENT_VERSION)
+               ThrowErr(Exc::InternalError, "It's not expected version");
+
+       RawBuffer salt;
+       if (domainKEKInfo.backend == (int)CryptoBackend::SecureElement) {
+#if SE_BACKEND_ENABLED
+               salt = Crypto::SE::Internals::encryptWithDbpKey((unsigned char*)domainKEKInfo.salt,
+                                                               MAX_SALT_SIZE,
+                                                               (unsigned char*)domainKEKInfo.iv,
+                                                               MAX_IV_SIZE);
+#else
+               ThrowErr(Exc::InternalError, "It's not expected backend");
+#endif
+       } else if (domainKEKInfo.backend == (int)CryptoBackend::OpenSSL) {
+               salt = RawBuffer(domainKEKInfo.salt, domainKEKInfo.salt + MAX_SALT_SIZE);
+       } else {
+               ThrowErr(Exc::InternalError, "It's not expected backend");
+       }
+
+       return PBKDF(concatPasswordClient, salt.data(), salt.size());
+}
+
 // derives a key (PKEK2) from DomainKEK and custom client string (may be a client id or uid)
 KeyData makePKEK2(const uint8_t *domainKEK, const std::string &client)
 {
-       KeyData key;
-       if (!PKCS5_PBKDF2_HMAC_SHA1(client.c_str(),
-                                   client.size(),
-                                   domainKEK,
-                                   MAX_SALT_SIZE,
-                                   PBKDF2_ITERATIONS,
-                                   key.size(),
-                                   key.data())) {
-               ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR");
-       }
-       return key;
+       return PBKDF(client, domainKEK, MAX_SALT_SIZE);
 }
 
 void unwrapDomainKEK(const RawBuffer &wrappedDomainKEKbuffer,
                      const Password &password,
-                     KeyAndInfoContainer &domainKEK)
+                     DomainKEKAndInfo &domainKEK)
 {
-       WrappedKeyAndInfoContainer wrappedDomainKEK(wrappedDomainKEKbuffer.data());
-
-       KeyData PKEK1 = makePKEK1(wrappedDomainKEK.getWrappedKeyAndInfo().keyInfo, password);
+       DomainKEKAndInfo wrappedDomainKEK(wrappedDomainKEKbuffer);
+       KeyData PKEK1 = makePKEK1(wrappedDomainKEK.info, password);
 
        int keyLength;
-       if (0 > (keyLength = decryptAes256Gcm(wrappedDomainKEK.getWrappedKeyAndInfo().wrappedKey,
-                                             wrappedDomainKEK.getWrappedKeyAndInfo().keyInfo.keyLength,
-                                             wrappedDomainKEK.getWrappedKeyAndInfo().keyInfo.tag,
+       if (0 > (keyLength = decryptAes256Gcm(wrappedDomainKEK.key,
+                                             wrappedDomainKEK.info.keyLength,
+                                             wrappedDomainKEK.info.tag,
                                              PKEK1.data(),
-                                             wrappedDomainKEK.getWrappedKeyAndInfo().keyInfo.iv,
-                                             domainKEK.getKeyAndInfo().key)))
+                                             wrappedDomainKEK.info.iv,
+                                             domainKEK.key)))
                ThrowErr(Exc::AuthenticationFailed, "DomainKEK decryption failed");
 
-       domainKEK.setKeyInfo(&(wrappedDomainKEK.getWrappedKeyAndInfo().keyInfo));
-       domainKEK.setKeyInfoKeyLength(static_cast<unsigned int>(keyLength));
+       domainKEK.setKeyInfo(wrappedDomainKEK.info);
+       domainKEK.info.keyLength = static_cast<uint32_t>(keyLength);
 }
 
-RawBuffer wrapDomainKEK(KeyAndInfoContainer &domainKEK, const Password &password)
+RawBuffer wrapDomainKEK(DomainKEKAndInfo &domainKEK, const Password &password)
 {
-       KeyData PKEK1 = makePKEK1(domainKEK.getKeyAndInfo().keyInfo, password);
+       KeyData PKEK1 = makePKEK1(domainKEK.info, password);
 
-       WrappedKeyAndInfoContainer wrappedDomainKEK = WrappedKeyAndInfoContainer();
-       wrappedDomainKEK.setKeyInfo(&(domainKEK.getKeyAndInfo().keyInfo));
+       DomainKEKAndInfo wrappedDomainKEK;
+       wrappedDomainKEK.setKeyInfo(domainKEK.info);
 
        int wrappedLength;
-       if (0 > (wrappedLength = encryptAes256Gcm(domainKEK.getKeyAndInfo().key,
-                                                 domainKEK.getKeyAndInfo().keyInfo.keyLength,
+       if (0 > (wrappedLength = encryptAes256Gcm(domainKEK.key,
+                                                 domainKEK.info.keyLength,
                                                  PKEK1.data(),
-                                                 domainKEK.getKeyAndInfo().keyInfo.iv,
-                                                 wrappedDomainKEK.getWrappedKeyAndInfo().wrappedKey,
-                                                 wrappedDomainKEK.getWrappedKeyAndInfo().keyInfo.tag)))
+                                                 domainKEK.info.iv,
+                                                 wrappedDomainKEK.key,
+                                                 wrappedDomainKEK.info.tag)))
                ThrowErr(Exc::InternalError, "DomainKEK encryption failed");
 
-       wrappedDomainKEK.setKeyInfoKeyLength(static_cast<unsigned int>(wrappedLength));
-       return toRawBuffer(wrappedDomainKEK.getWrappedKeyAndInfo());
+       wrappedDomainKEK.info.keyLength = static_cast<uint32_t>(wrappedLength);
+       return toRawBuffer(wrappedDomainKEK);
 }
 
 template <size_t N>
@@ -211,95 +233,6 @@ bool randomize(uint8_t (&array)[N])
 
 } // anonymous namespace
 
-WrappedKeyAndInfoContainer::WrappedKeyAndInfoContainer()
-{
-       memset(&wrappedKeyAndInfo, 0, sizeof(WrappedKeyAndInfo));
-}
-
-WrappedKeyAndInfoContainer::WrappedKeyAndInfoContainer(const unsigned char
-               *data)
-{
-       memcpy(&wrappedKeyAndInfo, data, sizeof(WrappedKeyAndInfo));
-
-       if (wrappedKeyAndInfo.keyInfo.keyLength > sizeof(wrappedKeyAndInfo.wrappedKey)) {
-               ThrowErr(Exc::InternalError,
-                        "Wrapped key info is corrupted. Key length exceeds the size of the key buffer.");
-       }
-
-       size_t maxlen = sizeof(wrappedKeyAndInfo.keyInfo.client);
-       if (strnlen(wrappedKeyAndInfo.keyInfo.client, maxlen) == maxlen) {
-               ThrowErr(Exc::InternalError,
-                        "Wrapped key info is corrupted. Client id is not NULL terminated.");
-       }
-}
-
-WrappedKeyAndInfo &WrappedKeyAndInfoContainer::getWrappedKeyAndInfo()
-{
-       return wrappedKeyAndInfo;
-}
-
-void WrappedKeyAndInfoContainer::setKeyInfoKeyLength(const unsigned int length)
-{
-       wrappedKeyAndInfo.keyInfo.keyLength = length;
-}
-
-void WrappedKeyAndInfoContainer::setKeyInfoClient(const std::string resized_client)
-{
-       if (resized_client.size() >= sizeof(wrappedKeyAndInfo.keyInfo.client)) {
-               ThrowErr(Exc::InternalError, "Client name too long");
-       }
-
-       strcpy(wrappedKeyAndInfo.keyInfo.client, resized_client.c_str());
-}
-
-void WrappedKeyAndInfoContainer::setKeyInfoSalt(const unsigned char *salt,
-               const int size)
-{
-       memcpy(wrappedKeyAndInfo.keyInfo.salt, salt, size);
-}
-
-void WrappedKeyAndInfoContainer::setKeyInfo(const KeyComponentsInfo
-               *keyComponentsInfo)
-{
-       memcpy(&(wrappedKeyAndInfo.keyInfo), keyComponentsInfo,
-                  sizeof(KeyComponentsInfo));
-}
-
-WrappedKeyAndInfoContainer::~WrappedKeyAndInfoContainer()
-{
-}
-
-KeyAndInfoContainer::KeyAndInfoContainer()
-{
-       memset(&keyAndInfo, 0, sizeof(KeyAndInfo));
-}
-
-KeyAndInfoContainer::KeyAndInfoContainer(const unsigned char *data)
-{
-       memcpy(&keyAndInfo, data, sizeof(KeyAndInfo));
-}
-
-KeyAndInfo &KeyAndInfoContainer::getKeyAndInfo()
-{
-       return keyAndInfo;
-}
-
-void KeyAndInfoContainer::setKeyInfoKeyLength(unsigned int length)
-{
-       keyAndInfo.keyInfo.keyLength = length;
-}
-
-void KeyAndInfoContainer::setKeyInfo(const KeyComponentsInfo *keyComponentsInfo)
-{
-       memcpy(&(keyAndInfo.keyInfo), keyComponentsInfo, sizeof(KeyComponentsInfo));
-}
-
-KeyAndInfoContainer::~KeyAndInfoContainer()
-{
-       // overwrite key
-       ZeroMemory(reinterpret_cast<unsigned char*>(&keyAndInfo), sizeof(KeyAndInfo));
-}
-
 KeyProvider::KeyProvider() :
        m_domainKEK(NULL),
        m_isInitialized(false)
@@ -310,17 +243,16 @@ KeyProvider::KeyProvider() :
 KeyProvider::KeyProvider(
        const RawBuffer &domainKEKInWrapForm,
        const Password &password) :
-       m_domainKEK(new KeyAndInfoContainer()),
+       m_domainKEK(new DomainKEKAndInfo()),
        m_isInitialized(true)
 {
-       if (!m_isInitialized)
-               ThrowErr(Exc::InternalError, "Object not initialized!. Should not happened");
-
-       if (domainKEKInWrapForm.size() != sizeof(WrappedKeyAndInfo)) {
-               LogError("input size:" << domainKEKInWrapForm.size()
-                                << " Expected: " << sizeof(WrappedKeyAndInfo));
-               ThrowErr(Exc::InternalError,
-                                "buffer doesn't have proper size to store WrappedKeyAndInfo in KeyProvider Constructor");
+       if (domainKEKInWrapForm.size() != sizeof(DomainKEKAndInfo)) {
+               LogWarning("Input size:" << domainKEKInWrapForm.size()
+                          << " Expected: " << sizeof(DomainKEKAndInfo));
+               LogWarning("Buffer doesn't have proper size to store DomainKEKAndInfo in KeyProvider"
+                          "Constructor");
+               m_isInitialized = false;
+               return;
        }
 
        unwrapDomainKEK(domainKEKInWrapForm, password, *m_domainKEK);
@@ -349,23 +281,21 @@ KeyProvider::KeyProvider(KeyProvider &&second)
        second.m_domainKEK = NULL;
 }
 
-bool KeyProvider::isInitialized()
+bool KeyProvider::isInitialized() const
 {
        return m_isInitialized;
 }
 
-RawBuffer KeyProvider::getPureDomainKEK()
+RawBuffer KeyProvider::getPureDomainKEK() const
 {
        if (!m_isInitialized)
                ThrowErr(Exc::InternalError, "Object not initialized!");
 
        // TODO secure
-       return RawBuffer(m_domainKEK->getKeyAndInfo().key,
-                                        (m_domainKEK->getKeyAndInfo().key) +
-                                        m_domainKEK->getKeyAndInfo().keyInfo.keyLength);
+       return RawBuffer(m_domainKEK->key, m_domainKEK->key + m_domainKEK->info.keyLength);
 }
 
-RawBuffer KeyProvider::getWrappedDomainKEK(const Password &password)
+RawBuffer KeyProvider::getWrappedDomainKEK(const Password &password) const
 {
        if (!m_isInitialized)
                ThrowErr(Exc::InternalError, "Object not initialized!");
@@ -373,52 +303,44 @@ RawBuffer KeyProvider::getWrappedDomainKEK(const Password &password)
        return wrapDomainKEK(*m_domainKEK, password);
 }
 
-
-RawBuffer KeyProvider::getPureDEK(const RawBuffer &DEKInWrapForm)
+RawBuffer KeyProvider::getPureDEK(const RawBuffer &wrappedDEKbuffer) const
 {
        if (!m_isInitialized)
                ThrowErr(Exc::InternalError, "Object not initialized!");
 
-       if (DEKInWrapForm.size() != sizeof(WrappedKeyAndInfo)) {
-               LogError("input size:" << DEKInWrapForm.size()
-                                << " Expected: " << sizeof(WrappedKeyAndInfo));
+       if (wrappedDEKbuffer.size() != sizeof(DEKAndInfo)) {
+               LogError("input size:" << wrappedDEKbuffer.size() << " Expected: " << sizeof(DEKAndInfo));
+
                ThrowErr(Exc::InternalError,
-                                "buffer doesn't have proper size to store "
-                                "WrappedKeyAndInfo in KeyProvider::getPureDEK");
+                        "buffer doesn't have proper size to store KeyAndInfo in KeyProvider::getPureDEK");
        }
 
-       KeyAndInfoContainer kmcDEK = KeyAndInfoContainer();
-       WrappedKeyAndInfoContainer wkmcDEK = WrappedKeyAndInfoContainer(
-                       DEKInWrapForm.data());
+       DEKAndInfo DEK;
+       DEKAndInfo wrappedDEK(wrappedDEKbuffer);
 
-       KeyData PKEK2 = makePKEK2(m_domainKEK->getKeyAndInfo().key,
-                                 wkmcDEK.getWrappedKeyAndInfo().keyInfo.client);
+       KeyData PKEK2 = makePKEK2(m_domainKEK->key, wrappedDEK.info.client);
 
        int keyLength;
-       if (0 > (keyLength = decryptAes256Gcm(
-                                                        wkmcDEK.getWrappedKeyAndInfo().wrappedKey,
-                                                        wkmcDEK.getWrappedKeyAndInfo().keyInfo.keyLength,
-                                                        wkmcDEK.getWrappedKeyAndInfo().keyInfo.tag,
-                                                        PKEK2.data(),
-                                                        wkmcDEK.getWrappedKeyAndInfo().keyInfo.iv,
-                                                        kmcDEK.getKeyAndInfo().key)))
-               ThrowErr(Exc::InternalError,
-                                "UnwrapDEK Failed in KeyProvider::getPureDEK");
+       if (0 > (keyLength = decryptAes256Gcm(wrappedDEK.key,
+                                             wrappedDEK.info.keyLength,
+                                             wrappedDEK.info.tag,
+                                             PKEK2.data(),
+                                             wrappedDEK.info.iv,
+                                             DEK.key)))
+               ThrowErr(Exc::InternalError, "UnwrapDEK Failed in KeyProvider::getPureDEK");
 
-       kmcDEK.setKeyInfoKeyLength((unsigned int)keyLength);
+       DEK.info.keyLength = static_cast<uint32_t>(keyLength);
 
        LogDebug("getPureDEK SUCCESS");
-       return RawBuffer(
-                          kmcDEK.getKeyAndInfo().key,
-                          (kmcDEK.getKeyAndInfo().key) + kmcDEK.getKeyAndInfo().keyInfo.keyLength);
+       return RawBuffer(DEK.key, DEK.key + DEK.info.keyLength);
 }
 
-RawBuffer KeyProvider::generateDEK(const std::string &client)
+RawBuffer KeyProvider::generateDEK(const std::string &client) const
 {
        if (!m_isInitialized)
                ThrowErr(Exc::InternalError, "Object not initialized!");
 
-       WrappedKeyAndInfoContainer wkmcDEK = WrappedKeyAndInfoContainer();
+       DEKAndInfo wrappedDEK;
        std::string resized_client;
 
        if (client.length() < MAX_CLIENT_ID_SIZE)
@@ -426,84 +348,78 @@ RawBuffer KeyProvider::generateDEK(const std::string &client)
        else
                resized_client = client.substr(0, MAX_CLIENT_ID_SIZE - 1);
 
-       uint8_t key[MAX_KEY_SIZE];
+       uint8_t DEK[MAX_KEY_SIZE];
 
-       if (!randomize(key) || !randomize(wkmcDEK.getWrappedKeyAndInfo().keyInfo.iv))
+       if (!randomize(DEK) || !randomize(wrappedDEK.info.iv))
                ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR");
 
-       KeyData PKEK2 = makePKEK2(m_domainKEK->getKeyAndInfo().key, resized_client);
+       KeyData PKEK2 = makePKEK2(m_domainKEK->key, resized_client);
 
        int wrappedKeyLength;
-       if (0 > (wrappedKeyLength = encryptAes256Gcm(key,
-                                                    m_domainKEK->getKeyAndInfo().keyInfo.keyLength,
+       if (0 > (wrappedKeyLength = encryptAes256Gcm(DEK,
+                                                    sizeof(DEK),
                                                     PKEK2.data(),
-                                                    wkmcDEK.getWrappedKeyAndInfo().keyInfo.iv,
-                                                    wkmcDEK.getWrappedKeyAndInfo().wrappedKey,
-                                                    wkmcDEK.getWrappedKeyAndInfo().keyInfo.tag)))
+                                                    wrappedDEK.info.iv,
+                                                    wrappedDEK.key,
+                                                    wrappedDEK.info.tag)))
                ThrowErr(Exc::InternalError, "GenerateDEK Failed in KeyProvider::generateDEK");
 
-       wkmcDEK.setKeyInfoKeyLength((unsigned int)wrappedKeyLength);
-       wkmcDEK.setKeyInfoClient(resized_client);
+       wrappedDEK.info.keyLength = static_cast<uint32_t>(wrappedKeyLength);
+       wrappedDEK.setKeyInfoClient(resized_client);
 
        LogDebug("GenerateDEK Success");
-       return toRawBuffer(wkmcDEK.getWrappedKeyAndInfo());
+       return toRawBuffer(wrappedDEK);
 }
 
-RawBuffer KeyProvider::reencrypt(
-       const RawBuffer &domainKEKInWrapForm,
-       const Password &oldPass,
-       const Password &newPass)
+void KeyProvider::migrateDomainKEK(const RawBuffer &wrappedDomainKEKbuffer,
+                                   const Password &password)
 {
-       if (domainKEKInWrapForm.size() != sizeof(WrappedKeyAndInfo)) {
-               LogError("input size:" << domainKEKInWrapForm.size()
-                                << " Expected: " << sizeof(WrappedKeyAndInfo));
-               ThrowErr(Exc::InternalError,
-                                "buffer doesn't have proper size to store "
-                                "WrappedKeyAndInfo in KeyProvider::reencrypt");
-       }
+       DEKAndInfo wrappedOldDomainKEK(wrappedDomainKEKbuffer);
 
-       KeyAndInfoContainer domainKEK;
-       unwrapDomainKEK(domainKEKInWrapForm, oldPass, domainKEK);
-       return wrapDomainKEK(domainKEK, newPass);
-}
-
-RawBuffer KeyProvider::generateDomainKEK(
-       const std::string &user,
-       const Password &userPassword)
-{
-       WrappedKeyAndInfoContainer wkmcDKEK = WrappedKeyAndInfoContainer();
-
-       KeyAndInfoContainer domainKEK;
+       std::string concatPasswordClient(password.c_str());
+       concatPasswordClient += std::string(wrappedOldDomainKEK.info.client);
 
-       if (!randomize(domainKEK.getKeyAndInfo().keyInfo.salt) ||
-               !randomize(domainKEK.getKeyAndInfo().key) ||
-           !randomize(domainKEK.getKeyAndInfo().keyInfo.iv)) {
-               ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR");
-       }
+       KeyData PKEK1 = PBKDF(concatPasswordClient, wrappedOldDomainKEK.info.salt, MAX_SALT_SIZE);
 
-       domainKEK.setKeyInfoKeyLength(sizeof(domainKEK.getKeyAndInfo().key));
+       int keyLength;
+       if (0 > (keyLength = decryptAes256Gcm(wrappedOldDomainKEK.key,
+                                             wrappedOldDomainKEK.info.keyLength,
+                                             wrappedOldDomainKEK.info.tag,
+                                             PKEK1.data(),
+                                             wrappedOldDomainKEK.info.iv,
+                                             m_domainKEK->key)))
+               ThrowErr(Exc::AuthenticationFailed, "DomainKEK decryption failed");
 
-       if (user.size() >= sizeof(domainKEK.getKeyAndInfo().keyInfo.client)) {
-               ThrowErr(Exc::InternalError, "Client name too long");
-       }
-       strcpy(domainKEK.getKeyAndInfo().keyInfo.client, user.c_str());
+       DomainKEKInfo info(wrappedOldDomainKEK.info);
+       info.version = KEYCOMPONENT_VERSION;
+       info.backend = static_cast<uint32_t>(CryptoBackend::OpenSSL);
+#ifdef SE_BACKEND_ENABLED
+       info.backend = static_cast<uint32_t>(CryptoBackend::SecureElement);
+#endif
+       m_domainKEK->setKeyInfo(info);
 
-       return wrapDomainKEK(domainKEK, userPassword);
+       m_domainKEK->info.keyLength = static_cast<uint32_t>(keyLength);
+       m_isInitialized = true;
+       LogDebug("Migrate DomainKEK Success");
 }
 
-int KeyProvider::initializeLibrary()
+RawBuffer KeyProvider::generateDomainKEK(const std::string &user, const Password &userPassword)
 {
-       LogDebug("initializeLibrary Success");
-       return SUCCESS;
-}
+       DomainKEKAndInfo domainKEK;
 
-int KeyProvider::closeLibrary()
-{
-       LogDebug("closeLibrary Success");
-       return SUCCESS;
-}
+       if (!randomize(domainKEK.info.salt) ||
+           !randomize(domainKEK.key) ||
+           !randomize(domainKEK.info.iv)) {
+               ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR");
+       }
 
-KeyProvider::~KeyProvider()
-{
-       LogDebug("KeyProvider Destructor");
+       domainKEK.info.version = KEYCOMPONENT_VERSION;
+       domainKEK.info.backend = static_cast<uint32_t>(CryptoBackend::OpenSSL);
+#ifdef SE_BACKEND_ENABLED
+       domainKEK.info.backend = static_cast<uint32_t>(CryptoBackend::SecureElement);
+#endif
+       domainKEK.info.keyLength = sizeof(domainKEK.key);
+       domainKEK.setKeyInfoClient(user);
+
+       return wrapDomainKEK(domainKEK, userPassword);
 }