Refactor KeyProvider 11/282611/1
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Wed, 5 Oct 2022 13:51:33 +0000 (15:51 +0200)
committerKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Thu, 6 Oct 2022 11:09:06 +0000 (13:09 +0200)
Apply modifications while keeping key file format and encryption scheme
unchanged:
* Remove unused code
* Deduplicate code
* Unify key naming
* Simplify structures keeping various forms of keys and their metadata
* Update tests

Change-Id: I38caceb6c38bfecbdbbb290df39042ba7b17b394

misc/encryption_scheme/test_encryption-scheme.cpp
src/manager/main/key-manager-main.cpp
src/manager/service/ckm-logic.cpp
src/manager/service/key-provider.cpp
src/manager/service/key-provider.h
unit-tests/test_key-provider.cpp

index 53c5683..d129169 100644 (file)
@@ -82,25 +82,6 @@ struct TestConfig {
        }
 };
 
-struct KeyProviderLib {
-       KeyProviderLib()
-       {
-               try {
-                       KeyProvider::initializeLibrary();
-               } catch (const Exc::Exception &) {
-                       std::cout << "Library initialization failed!" << std::endl;
-               }
-       }
-       ~KeyProviderLib()
-       {
-               try {
-                       KeyProvider::closeLibrary();
-               } catch (const Exc::Exception &) {
-                       std::cout << "Library deinitialization failed!" << std::endl;
-               }
-       }
-};
-
 struct LogSetup {
        LogSetup()
        {
@@ -112,7 +93,6 @@ struct LogSetup {
 
 } // namespace anonymous
 
-BOOST_GLOBAL_FIXTURE(KeyProviderLib);
 BOOST_GLOBAL_FIXTURE(TestConfig);
 BOOST_GLOBAL_FIXTURE(LogSetup);
 BOOST_FIXTURE_TEST_SUITE(ENCRYPTION_SCHEME_TEST, OnlycapFixture)
index bb867b7..d1840c5 100644 (file)
@@ -122,8 +122,6 @@ int main(void)
 
                initializeEntropy();
 
-               CKM::KeyProvider::initializeLibrary();
-
                {
                        LogInfo("Start!");
                        CKM::SocketManager manager;
@@ -135,10 +133,6 @@ int main(void)
 
                        manager.MainLoop();
                }
-
-               // Manager has been destroyed and we may close external libraries.
-               LogInfo("Deinit SKMM and openssl");
-               CKM::KeyProvider::closeLibrary();
        } catch (const std::runtime_error &e) {
                LogError(e.what());
        }
index a81c05f..311884f 100644 (file)
@@ -240,7 +240,7 @@ void CKMLogic::loadDKEKFile(uid_t user, const Password &password)
 
        handle.keyProvider = KeyProvider(wrappedDKEK, password);
        if (!handle.keyProvider.isInitialized()) {
-               handle.keyProvider.migrateDKEK(wrappedDKEK, password);
+               handle.keyProvider.migrateDomainKEK(wrappedDKEK, password);
                fs.saveDKEK(handle.keyProvider.getWrappedDomainKEK(password));
                LogInfo("DKEK migrated");
        }
index ce908c7..24c48aa 100644 (file)
  *  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 <crypto-backend.h>
 #ifdef SE_BACKEND_ENABLED
 #include <se-backend/internals.h>
@@ -30,6 +34,10 @@ 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)
 {
@@ -127,100 +135,94 @@ int decryptAes256Gcm(const unsigned char *ciphertext,
 }
 
 typedef std::array<uint8_t, MAX_KEY_SIZE> KeyData;
+
+KeyData PBKDF(const std::string& pass, const unsigned char *salt, int saltlen)
+{
+       KeyData key;
+       if (!PKCS5_PBKDF2_HMAC_SHA1(pass.c_str(),
+                                   pass.size(),
+                                   salt,
+                                   saltlen,
+                                   PBKDF2_ITERATIONS,
+                                   key.size(),
+                                   key.data())) {
+               ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR");
+       }
+       return key;
+}
+
 // derives a key used for DomainKEK encryption (aka PKEK1) from random salt & user password
-KeyData makePKEK1(const KeyComponentsInfoDKEK& keyInfo, const Password &password)
+KeyData makePKEK1(const DomainKEKInfo& domainKEKInfo, const Password &password)
 {
        std::string concatPasswordClient(password.c_str());
-       concatPasswordClient += std::string(keyInfo.client);
-       KeyData key;
-       if (keyInfo.version != KEYCOMPONENT_VERSION)
+       concatPasswordClient += std::string(domainKEKInfo.client);
+
+       if (domainKEKInfo.version != KEYCOMPONENT_VERSION)
                ThrowErr(Exc::InternalError, "It's not expected version");
 
-#if SE_BACKEND_ENABLED
        RawBuffer salt;
-       if (keyInfo.backend == (int)CryptoBackend::SecureElement) {
-               salt = Crypto::SE::Internals::encryptWithDbpKey((unsigned char*)keyInfo.salt, MAX_SALT_SIZE,
-                                                                               (unsigned char*)keyInfo.iv, MAX_IV_SIZE);
-       } else {
-               salt = RawBuffer(keyInfo.salt, keyInfo.salt + MAX_SALT_SIZE);
-       }
+       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
-       if (keyInfo.backend != (int)CryptoBackend::OpenSSL)
                ThrowErr(Exc::InternalError, "It's not expected backend");
-
-       RawBuffer salt(keyInfo.salt, keyInfo.salt + MAX_SALT_SIZE);
 #endif
-       if (!PKCS5_PBKDF2_HMAC_SHA1(concatPasswordClient.c_str(),
-                                   concatPasswordClient.size(),
-                                   salt.data(),
-                                   salt.size(),
-                                   PBKDF2_ITERATIONS,
-                                   key.size(),
-                                   key.data())) {
-               ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR");
+       } 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 key;
+
+       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;
-       wrappedDomainKEK.setWrappedDKEKAndInfo(wrappedDomainKEKbuffer.data());
-       KeyData PKEK1 = makePKEK1(wrappedDomainKEK.getWrappedDKEKAndInfo().keyInfo, password);
+       DomainKEKAndInfo wrappedDomainKEK(wrappedDomainKEKbuffer);
+       KeyData PKEK1 = makePKEK1(wrappedDomainKEK.info, password);
 
        int keyLength;
-       if (0 > (keyLength = decryptAes256Gcm(wrappedDomainKEK.getWrappedDKEKAndInfo().wrappedKey,
-                                             wrappedDomainKEK.getWrappedDKEKAndInfo().keyInfo.keyLength,
-                                             wrappedDomainKEK.getWrappedDKEKAndInfo().keyInfo.tag,
+       if (0 > (keyLength = decryptAes256Gcm(wrappedDomainKEK.key,
+                                             wrappedDomainKEK.info.keyLength,
+                                             wrappedDomainKEK.info.tag,
                                              PKEK1.data(),
-                                             wrappedDomainKEK.getWrappedDKEKAndInfo().keyInfo.iv,
-                                             domainKEK.getDKEKAndInfo().key)))
+                                             wrappedDomainKEK.info.iv,
+                                             domainKEK.key)))
                ThrowErr(Exc::AuthenticationFailed, "DomainKEK decryption failed");
 
-       domainKEK.setKeyInfo(&(wrappedDomainKEK.getWrappedDKEKAndInfo().keyInfo));
-       domainKEK.setDKEKInfo(wrappedDomainKEK.getWrappedDKEKAndInfo().keyInfo.version,
-                                               wrappedDomainKEK.getWrappedDKEKAndInfo().keyInfo.backend);
-       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.getDKEKAndInfo().keyInfo, password);
+       KeyData PKEK1 = makePKEK1(domainKEK.info, password);
 
-       WrappedKeyAndInfoContainer wrappedDomainKEK = WrappedKeyAndInfoContainer();
-       wrappedDomainKEK.setKeyInfo(&(domainKEK.getDKEKAndInfo().keyInfo));
-       wrappedDomainKEK.setDKEKInfo(domainKEK.getDKEKAndInfo().keyInfo.version,
-                                                               domainKEK.getDKEKAndInfo().keyInfo.backend);
+       DomainKEKAndInfo wrappedDomainKEK;
+       wrappedDomainKEK.setKeyInfo(domainKEK.info);
 
        int wrappedLength;
-       if (0 > (wrappedLength = encryptAes256Gcm(domainKEK.getDKEKAndInfo().key,
-                                                 domainKEK.getDKEKAndInfo().keyInfo.keyLength,
+       if (0 > (wrappedLength = encryptAes256Gcm(domainKEK.key,
+                                                 domainKEK.info.keyLength,
                                                  PKEK1.data(),
-                                                 domainKEK.getDKEKAndInfo().keyInfo.iv,
-                                                 wrappedDomainKEK.getWrappedDKEKAndInfo().wrappedKey,
-                                                 wrappedDomainKEK.getWrappedDKEKAndInfo().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.getWrappedDKEKAndInfo());
+       wrappedDomainKEK.info.keyLength = static_cast<uint32_t>(wrappedLength);
+       return toRawBuffer(wrappedDomainKEK);
 }
 
 template <size_t N>
@@ -231,148 +233,6 @@ bool randomize(uint8_t (&array)[N])
 
 } // anonymous namespace
 
-WrappedKeyAndInfoContainer::WrappedKeyAndInfoContainer()
-{
-       memset(&wrappedKeyAndInfo, 0, sizeof(WrappedKeyAndInfo));
-       memset(&wrappedDKEKAndInfo, 0, sizeof(WrappedKeyAndInfoDKEK));
-}
-
-WrappedKeyAndInfo &WrappedKeyAndInfoContainer::getWrappedKeyAndInfo()
-{
-       return wrappedKeyAndInfo;
-}
-
-WrappedKeyAndInfoDKEK &WrappedKeyAndInfoContainer::getWrappedDKEKAndInfo()
-{
-       return wrappedDKEKAndInfo;
-}
-
-void WrappedKeyAndInfoContainer::setWrappedKeyAndInfo(
-               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.");
-       }
-}
-
-void WrappedKeyAndInfoContainer::setWrappedDKEKAndInfo(
-               const unsigned char *data)
-{
-       memcpy(&wrappedDKEKAndInfo, data, sizeof(WrappedKeyAndInfoDKEK));
-
-       if (wrappedDKEKAndInfo.keyInfo.keyLength > sizeof(wrappedDKEKAndInfo.wrappedKey)) {
-               ThrowErr(Exc::InternalError,
-                        "Wrapped key info is corrupted. Key length exceeds the size of the key buffer.");
-       }
-
-       size_t maxlen = sizeof(wrappedDKEKAndInfo.keyInfo.client);
-       if (strnlen(wrappedDKEKAndInfo.keyInfo.client, maxlen) == maxlen) {
-               ThrowErr(Exc::InternalError,
-                        "Wrapped key info is corrupted. Client id is not NULL terminated.");
-       }
-}
-
-void WrappedKeyAndInfoContainer::setKeyInfoKeyLength(const uint32_t length)
-{
-       wrappedKeyAndInfo.keyInfo.keyLength = length;
-       wrappedDKEKAndInfo.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");
-       }
-
-       strncpy(wrappedKeyAndInfo.keyInfo.client, resized_client.c_str(), resized_client.size());
-       strncpy(wrappedDKEKAndInfo.keyInfo.client, resized_client.c_str(), resized_client.size());
-}
-
-void WrappedKeyAndInfoContainer::setKeyInfoSalt(const unsigned char *salt,
-               const int size)
-{
-       memcpy(wrappedKeyAndInfo.keyInfo.salt, salt, size);
-       memcpy(wrappedDKEKAndInfo.keyInfo.salt, salt, size);
-}
-
-void WrappedKeyAndInfoContainer::setKeyInfo(const KeyComponentsInfo
-               *keyComponentsInfo)
-{
-       memcpy(&(wrappedKeyAndInfo.keyInfo), keyComponentsInfo,
-                  sizeof(KeyComponentsInfo));
-       wrappedDKEKAndInfo.keyInfo.set(wrappedKeyAndInfo.keyInfo);
-}
-
-void WrappedKeyAndInfoContainer::setDKEKInfo(const uint32_t version, const uint32_t backend)
-{
-       wrappedDKEKAndInfo.keyInfo.version = version;
-       wrappedDKEKAndInfo.keyInfo.backend = backend;
-}
-
-WrappedKeyAndInfoContainer::~WrappedKeyAndInfoContainer()
-{
-}
-
-KeyAndInfoContainer::KeyAndInfoContainer()
-{
-       memset(&keyAndInfo, 0, sizeof(KeyAndInfo));
-       memset(&DKEKAndInfo, 0, sizeof(KeyAndInfoDKEK));
-}
-
-KeyAndInfo &KeyAndInfoContainer::getKeyAndInfo()
-{
-       return keyAndInfo;
-}
-
-KeyAndInfoDKEK &KeyAndInfoContainer::getDKEKAndInfo()
-{
-       return DKEKAndInfo;
-}
-
-void KeyAndInfoContainer::setKeyAndInfo(const unsigned char *data)
-{
-       memcpy(&keyAndInfo, data, sizeof(KeyAndInfo));
-}
-
-void KeyAndInfoContainer::setDKEKAndInfo(const unsigned char *data)
-{
-       memcpy(&DKEKAndInfo, data, sizeof(KeyAndInfoDKEK));
-}
-
-void KeyAndInfoContainer::setKeyInfoKeyLength(const uint32_t length)
-{
-       keyAndInfo.keyInfo.keyLength = length;
-       DKEKAndInfo.keyInfo.keyLength = length;
-}
-
-void KeyAndInfoContainer::setKeyInfo(const KeyComponentsInfo *keyComponentsInfo)
-{
-       memcpy(&(keyAndInfo.keyInfo), keyComponentsInfo, sizeof(KeyComponentsInfo));
-       DKEKAndInfo.keyInfo.set(keyAndInfo.keyInfo);
-}
-
-void KeyAndInfoContainer::setDKEKInfo(const uint32_t version, const uint32_t backend)
-{
-       DKEKAndInfo.keyInfo.version = version;
-       DKEKAndInfo.keyInfo.backend = backend;
-}
-
-KeyAndInfoContainer::~KeyAndInfoContainer()
-{
-       // overwrite key
-       ZeroMemory(reinterpret_cast<unsigned char*>(&keyAndInfo), sizeof(KeyAndInfo));
-       ZeroMemory(reinterpret_cast<unsigned char*>(&DKEKAndInfo), sizeof(KeyAndInfoDKEK));
-}
-
 KeyProvider::KeyProvider() :
        m_domainKEK(NULL),
        m_isInitialized(false)
@@ -383,13 +243,14 @@ KeyProvider::KeyProvider() :
 KeyProvider::KeyProvider(
        const RawBuffer &domainKEKInWrapForm,
        const Password &password) :
-       m_domainKEK(new KeyAndInfoContainer()),
+       m_domainKEK(new DomainKEKAndInfo()),
        m_isInitialized(true)
 {
-       if (domainKEKInWrapForm.size() != sizeof(WrappedKeyAndInfoDKEK)) {
-               LogWarning("input size:" << domainKEKInWrapForm.size()
-                                << " Expected: " << sizeof(WrappedKeyAndInfoDKEK));
-               LogWarning("buffer doesn't have proper size to store WrappedKeyAndInfoDKEK 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;
        }
@@ -431,9 +292,7 @@ RawBuffer KeyProvider::getPureDomainKEK()
                ThrowErr(Exc::InternalError, "Object not initialized!");
 
        // TODO secure
-       return RawBuffer(m_domainKEK->getDKEKAndInfo().key,
-                                        (m_domainKEK->getDKEKAndInfo().key) +
-                                        m_domainKEK->getDKEKAndInfo().keyInfo.keyLength);
+       return RawBuffer(m_domainKEK->key, m_domainKEK->key + m_domainKEK->info.keyLength);
 }
 
 RawBuffer KeyProvider::getWrappedDomainKEK(const Password &password)
@@ -444,45 +303,36 @@ RawBuffer KeyProvider::getWrappedDomainKEK(const Password &password)
        return wrapDomainKEK(*m_domainKEK, password);
 }
 
-
-RawBuffer KeyProvider::getPureDEK(const RawBuffer &DEKInWrapForm)
+RawBuffer KeyProvider::getPureDEK(const RawBuffer &wrappedDEKbuffer)
 {
        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();
-       wkmcDEK.setWrappedKeyAndInfo(DEKInWrapForm.data());
+       DEKAndInfo DEK;
+       DEKAndInfo wrappedDEK(wrappedDEKbuffer);
 
-       KeyData PKEK2 = makePKEK2(m_domainKEK->getDKEKAndInfo().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)
@@ -490,7 +340,7 @@ RawBuffer KeyProvider::generateDEK(const std::string &client)
        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)
@@ -498,137 +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->getDKEKAndInfo().key, resized_client);
+       KeyData PKEK2 = makePKEK2(m_domainKEK->key, resized_client);
 
        int wrappedKeyLength;
-       if (0 > (wrappedKeyLength = encryptAes256Gcm(key,
-                                                    m_domainKEK->getDKEKAndInfo().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);
 }
 
-void KeyProvider::migrateDKEK(const RawBuffer &wrappedDomainKEKbuffer,
-                                       const Password &password)
+void KeyProvider::migrateDomainKEK(const RawBuffer &wrappedDomainKEKbuffer,
+                                   const Password &password)
 {
-       WrappedKeyAndInfo wrappedInfo;
-       if (wrappedDomainKEKbuffer.size() != sizeof(WrappedKeyAndInfo)) {
-               LogError("[migrateDKEK] Input size:" << wrappedDomainKEKbuffer.size() <<
-                                " Expected: " << sizeof(WrappedKeyAndInfo));
-               ThrowErr(Exc::InternalError,
-                                "buffer doesn't have proper size to store ");
-       }
-       memcpy(&wrappedInfo, wrappedDomainKEKbuffer.data(), sizeof(WrappedKeyAndInfo));
-
-       size_t maxlen = sizeof(wrappedInfo.keyInfo.client);
-       if (strnlen(wrappedInfo.keyInfo.client, maxlen) == maxlen) {
-               ThrowErr(Exc::InternalError,
-                        "Wrapped key info is corrupted. Client id is not NULL terminated.");
-       }
+       DEKAndInfo wrappedOldDomainKEK(wrappedDomainKEKbuffer);
 
-       KeyComponentsInfo keyInfo = wrappedInfo.keyInfo;
        std::string concatPasswordClient(password.c_str());
-       concatPasswordClient += std::string(keyInfo.client);
+       concatPasswordClient += std::string(wrappedOldDomainKEK.info.client);
 
-       KeyData PKEK1;
-       if (!PKCS5_PBKDF2_HMAC_SHA1(concatPasswordClient.c_str(),
-                                   concatPasswordClient.size(),
-                                   keyInfo.salt,
-                                   MAX_SALT_SIZE,
-                                   PBKDF2_ITERATIONS,
-                                   PKEK1.size(),
-                                   PKEK1.data())) {
-               ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR");
-       }
+       KeyData PKEK1 = PBKDF(concatPasswordClient, wrappedOldDomainKEK.info.salt, MAX_SALT_SIZE);
 
        int keyLength;
-       if (0 > (keyLength = decryptAes256Gcm(wrappedInfo.wrappedKey,
-                                             keyInfo.keyLength,
-                                             keyInfo.tag,
+       if (0 > (keyLength = decryptAes256Gcm(wrappedOldDomainKEK.key,
+                                             wrappedOldDomainKEK.info.keyLength,
+                                             wrappedOldDomainKEK.info.tag,
                                              PKEK1.data(),
-                                             keyInfo.iv,
-                                             m_domainKEK->getDKEKAndInfo().key)))
+                                             wrappedOldDomainKEK.info.iv,
+                                             m_domainKEK->key)))
                ThrowErr(Exc::AuthenticationFailed, "DomainKEK decryption failed");
 
-       m_domainKEK->getDKEKAndInfo().keyInfo.set(keyInfo);
-       m_domainKEK->setDKEKInfo(KEYCOMPONENT_VERSION, (uint32_t)CryptoBackend::OpenSSL);
+       DomainKEKInfo info(wrappedOldDomainKEK.info);
+       info.version = KEYCOMPONENT_VERSION;
+       info.backend = static_cast<uint32_t>(CryptoBackend::OpenSSL);
 #ifdef SE_BACKEND_ENABLED
-       m_domainKEK->setDKEKInfo(KEYCOMPONENT_VERSION, (uint32_t)CryptoBackend::SecureElement);
+       info.backend = static_cast<uint32_t>(CryptoBackend::SecureElement);
 #endif
-       m_domainKEK->setKeyInfoKeyLength(static_cast<unsigned int>(keyLength));
-       m_isInitialized = true;
-       LogDebug("Migrate DKEK Success");
-}
+       m_domainKEK->setKeyInfo(info);
 
-RawBuffer KeyProvider::reencrypt(
-       const RawBuffer &domainKEKInWrapForm,
-       const Password &oldPass,
-       const Password &newPass)
-{
-       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");
-       }
-
-       KeyAndInfoContainer domainKEK;
-       unwrapDomainKEK(domainKEKInWrapForm, oldPass, domainKEK);
-       return wrapDomainKEK(domainKEK, newPass);
+       m_domainKEK->info.keyLength = static_cast<uint32_t>(keyLength);
+       m_isInitialized = true;
+       LogDebug("Migrate DomainKEK Success");
 }
 
-RawBuffer KeyProvider::generateDomainKEK(
-       const std::string &user,
-       const Password &userPassword)
+RawBuffer KeyProvider::generateDomainKEK(const std::string &user, const Password &userPassword)
 {
-       KeyAndInfoContainer domainKEK;
+       DomainKEKAndInfo domainKEK;
 
-       if (!randomize(domainKEK.getDKEKAndInfo().keyInfo.salt) ||
-               !randomize(domainKEK.getDKEKAndInfo().key) ||
-           !randomize(domainKEK.getDKEKAndInfo().keyInfo.iv)) {
+       if (!randomize(domainKEK.info.salt) ||
+           !randomize(domainKEK.key) ||
+           !randomize(domainKEK.info.iv)) {
                ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR");
        }
 
-       domainKEK.setDKEKInfo(KEYCOMPONENT_VERSION, (uint32_t)CryptoBackend::OpenSSL);
+       domainKEK.info.version = KEYCOMPONENT_VERSION;
+       domainKEK.info.backend = static_cast<uint32_t>(CryptoBackend::OpenSSL);
 #ifdef SE_BACKEND_ENABLED
-       domainKEK.setDKEKInfo(KEYCOMPONENT_VERSION, (uint32_t)CryptoBackend::SecureElement);
+       domainKEK.info.backend = static_cast<uint32_t>(CryptoBackend::SecureElement);
 #endif
-       domainKEK.setKeyInfoKeyLength(sizeof(domainKEK.getDKEKAndInfo().key));
-       if (user.size() >= sizeof(domainKEK.getDKEKAndInfo().keyInfo.client)) {
-               ThrowErr(Exc::InternalError, "Client name too long");
-       }
-       strncpy(domainKEK.getDKEKAndInfo().keyInfo.client, user.c_str(), user.size());
+       domainKEK.info.keyLength = sizeof(domainKEK.key);
+       domainKEK.setKeyInfoClient(user);
 
        return wrapDomainKEK(domainKEK, userPassword);
 }
-
-int KeyProvider::initializeLibrary()
-{
-       LogDebug("initializeLibrary Success");
-       return SUCCESS;
-}
-
-int KeyProvider::closeLibrary()
-{
-       LogDebug("closeLibrary Success");
-       return SUCCESS;
-}
-
-KeyProvider::~KeyProvider()
-{
-       LogDebug("KeyProvider Destructor");
-}
index dcc695e..5acfef5 100644 (file)
 
 #pragma once
 
-#include <string.h>
 #include <stdint.h>
-#include <openssl/rand.h>
-#include <openssl/err.h>
-#include <openssl/evp.h>
-#include <openssl/sha.h>
-#include <memory>
+#include <string.h>
 
-#include <ckm/ckm-type.h>
+#include <string>
 
-#ifndef SUCCESS
-#define SUCCESS               0
-#endif
-#ifndef ERROR
-#define ERROR                -1
-#endif
-#ifndef INVALID_ARGUMENTS
-#define INVALID_ARGUMENTS    -2
-#endif
-#ifndef VERIFY_DATA_ERROR
-#define VERIFY_DATA_ERROR    -3
-#endif
-#ifndef OPENSSL_ENGINE_ERROR
-#define OPENSSL_ENGINE_ERROR -4
-#endif
-#ifndef UNKNOWN_ERROR
-#define UNKNOWN_ERROR        -5
-#endif
-
-#define AES256_KEY_LEN_BITS   256
-#define AES256_KEY_LEN_BYTSE  (AES256_KEY_LEN_BITS / 8)
-// Unused
-//#define AES_GCM_TAG_SIZE      32
-
-#define PBKDF2_SALT_LEN       16
-#define PBKDF2_ITERATIONS     4096
+#include <exception.h>
+#include <ckm/ckm-type.h>
+#include <dpl/log/log.h>
 
 #define MAX_IV_SIZE           16
 #define MAX_SALT_SIZE         16
 #define MAX_KEY_SIZE          32
-#define MAX_WRAPPED_KEY_SIZE  32
 #define MAX_CLIENT_ID_SIZE    32
-#define DOMAIN_NAME_SIZE      32
 
 namespace CKM {
 
-const uint32_t KEYCOMPONENT_VERSION = 2;
-
-typedef struct KeyComponentsInfo_ {
+struct KeyInfo {
        uint32_t keyLength;
        char client[MAX_CLIENT_ID_SIZE];
        uint8_t salt[MAX_SALT_SIZE];
        uint8_t iv[MAX_IV_SIZE];
        uint8_t tag[MAX_IV_SIZE];
-} KeyComponentsInfo;
-
-typedef struct KeyAndInfo_ {
-       KeyComponentsInfo keyInfo;
-       uint8_t key[MAX_KEY_SIZE];
-} KeyAndInfo;
-
-typedef struct WrappedKeyAndInfo_ {
-       KeyComponentsInfo keyInfo;
-       uint8_t wrappedKey[MAX_WRAPPED_KEY_SIZE];
-} WrappedKeyAndInfo;
+};
 
-typedef struct KeyComponentsInfoDKEK_ : KeyComponentsInfo{
+struct DomainKEKInfo : KeyInfo {
+       DomainKEKInfo() = default;
+       DomainKEKInfo(const KeyInfo& info) : KeyInfo(info) {}
        uint32_t version;
        uint32_t backend;
-       void set(const KeyComponentsInfo &src) {
-               keyLength = src.keyLength;
-               memcpy(&client, &src.client, MAX_CLIENT_ID_SIZE);
-               memcpy(&salt, &src.salt, MAX_SALT_SIZE);
-               memcpy(&iv, &src.iv, MAX_IV_SIZE);
-               memcpy(&tag, &src.tag, MAX_IV_SIZE);
+};
+
+template <typename T>
+struct KeyAndInfo final {
+       KeyAndInfo() {
+               memset(this, 0, sizeof(*this));
        }
-} KeyComponentsInfoDKEK;
 
-typedef struct KeyAndInfoDKEK_ {
-       KeyComponentsInfoDKEK keyInfo;
-       uint8_t key[MAX_KEY_SIZE];
-} KeyAndInfoDKEK;
+       explicit KeyAndInfo(const RawBuffer& data) {
+               if (data.size() != sizeof(*this)) {
+                       LogError("Data size: " << data.size() << " Expected: " << sizeof(*this));
+                       ThrowErr(Exc::InternalError, "buffer doesn't have proper size to store ");
+               }
 
-typedef struct WrappedKeyAndInfoDKEK_ {
-       KeyComponentsInfoDKEK keyInfo;
-       uint8_t wrappedKey[MAX_WRAPPED_KEY_SIZE];
-} WrappedKeyAndInfoDKEK;
+               memcpy(this, data.data(), sizeof(*this));
 
-class WrappedKeyAndInfoContainer {
-public:
-       WrappedKeyAndInfoContainer();
-       WrappedKeyAndInfo &getWrappedKeyAndInfo();
-       WrappedKeyAndInfoDKEK &getWrappedDKEKAndInfo();
-       void setWrappedKeyAndInfo(const unsigned char *);
-       void setWrappedDKEKAndInfo(const unsigned char *);
-       void setKeyInfoKeyLength(const uint32_t);
-       void setKeyInfoClient(const std::string);
-       void setKeyInfoSalt(const unsigned char *, const int);
-       void setKeyInfo(const KeyComponentsInfo *);
-       void setDKEKInfo(const uint32_t, const uint32_t);
-       ~WrappedKeyAndInfoContainer();
+               if (info.keyLength > sizeof(key)) {
+                       ThrowErr(Exc::InternalError,
+                                        "Key info is corrupted. Key length exceeds the size of the key buffer.");
+               }
 
-private:
-       WrappedKeyAndInfo wrappedKeyAndInfo;
-       WrappedKeyAndInfoDKEK wrappedDKEKAndInfo;
-};
+               size_t maxlen = sizeof(info.client);
+               if (strnlen(info.client, maxlen) == maxlen) {
+                       ThrowErr(Exc::InternalError,
+                                        "Key info is corrupted. Client id is not NULL terminated.");
+               }
+       }
 
-class KeyAndInfoContainer {
-public:
-       KeyAndInfoContainer();
-       KeyAndInfo &getKeyAndInfo();
-       KeyAndInfoDKEK &getDKEKAndInfo();
-       void setKeyAndInfo(const unsigned char *);
-       void setDKEKAndInfo(const unsigned char *);
-       void setKeyInfoKeyLength(const uint32_t);
-       void setKeyInfo(const KeyComponentsInfo *);
-       void setDKEKInfo(const uint32_t, const uint32_t);
-       ~KeyAndInfoContainer();
+       void setKeyInfo(const T& info_) {
+               memcpy(&(info), &info_, sizeof(info));
+       }
 
-private:
-       KeyAndInfo keyAndInfo;
-       KeyAndInfoDKEK DKEKAndInfo;
+       void setKeyInfoClient(const std::string& resized_client) {
+               if (resized_client.size() >= sizeof(info.client)) {
+                       ThrowErr(Exc::InternalError, "Client name too long");
+               }
+
+               strncpy(info.client, resized_client.c_str(), resized_client.size());
+       }
+
+       ~KeyAndInfo() {
+               // overwrite key
+               ZeroMemory(key, sizeof(key));
+       }
+
+       T info;
+       uint8_t key[MAX_KEY_SIZE];
 };
 
+typedef KeyAndInfo<DomainKEKInfo> DomainKEKAndInfo;
+typedef KeyAndInfo<KeyInfo> DEKAndInfo; // it's also old DomainKEK form
+
 
 // This is internal api so all functions should throw exception on errors.
 class KeyProvider {
 public:
-       // To store in std containers
        KeyProvider();
-       // In constructor you must check if SKMM is initialized. On error -> exception
-       // keyInWrapForm should be used like this:
-       // if (keyInWrapForm.size() != sizeof(WrappedKeyAndInfo))
-       //     throw exception; // buffer does not have proper size to store WrappedKeyAndInfo
-       // WrappedKeyAndInfo *wkm = static_cast<WrappedKeyAndInfo>(keyInWrapForm.data());
-       KeyProvider(const RawBuffer &domainKEKInWrapForm, const Password &password);
+       KeyProvider(const RawBuffer &wrappedDomainKEKbuffer, const Password &password);
 
        KeyProvider(KeyProvider &&);
        KeyProvider(const KeyProvider &) = delete;
@@ -164,13 +115,11 @@ public:
        RawBuffer getPureDomainKEK();
 
        // Returns Key in form used to store key in file
-       // Requied by Control::resetPassword(const RawBuffer &newPassword);
-       // This api should be used only on Tizen 2.2.1
        RawBuffer getWrappedDomainKEK(const Password &password);
 
        // Unwraps (decrypts) a DEK using a key derived from DomainKEK and data stored in wrapped key
        // info. It returns the DEK in unencrypted form.
-       RawBuffer getPureDEK(const RawBuffer &DEKInWrapForm);
+       RawBuffer getPureDEK(const RawBuffer &wrappedDEKbuffer);
 
        // Generates a random DEK and encrypts it using a key derived from DomainKEK and custom client
        // string (not to be confused with ClientId). The function returns  the DEK in wrapped
@@ -178,31 +127,14 @@ public:
        // application keys.
        RawBuffer generateDEK(const std::string &client);
 
-       // used by change user password. On error -> exception
-       static RawBuffer reencrypt(
-               const RawBuffer &domainKEKInWrapForm,
-               const Password &oldPass,
-               const Password &newPass);
-
        // First run of application for some user. DomainKEK was not created yet. We must create one.
        // This key will be used to encrypt user database.
-       static RawBuffer generateDomainKEK(const std::string &user,
-                                                                          const Password &userPassword);
-
-       void migrateDKEK(const RawBuffer &wrappedDomainKEKbuffer,
-                                               const Password &password);
-       RawBuffer migrateDBDEK(const RawBuffer &DEKInWrapForm);
-
-       // This will be called by framework at the begin of the program
-       static int initializeLibrary();
-       // This will be called by framework at the end of the program
-       static int closeLibrary();
+       static RawBuffer generateDomainKEK(const std::string &user, const Password &userPassword);
 
-       virtual ~KeyProvider();
+       void migrateDomainKEK(const RawBuffer &wrappedDomainKEKbuffer, const Password &password);
 
 private:
-       // KeyAndInfoContainer class
-       std::shared_ptr<KeyAndInfoContainer> m_domainKEK;
+       std::shared_ptr<DomainKEKAndInfo> m_domainKEK;
        bool m_isInitialized;
 };
 
index 7d9793f..2d6530b 100644 (file)
@@ -62,19 +62,22 @@ BOOST_AUTO_TEST_SUITE(KEY_PROVIDER_TEST)
 NEGATIVE_TEST_CASE(KeyProvider_wrong_size)
 {
        RawBuffer wdkek = makeDefaultWrappedDomainKEK();
+       KeyProvider kp;
 
        wdkek.push_back(0);
-       BOOST_REQUIRE_THROW(KeyProvider(wdkek, PASSWORD), Exc::InternalError);
+       BOOST_REQUIRE_NO_THROW(kp = KeyProvider(wdkek, PASSWORD));
+       BOOST_REQUIRE(!kp.isInitialized());
 
        wdkek.pop_back();
        wdkek.pop_back();
-       BOOST_REQUIRE_THROW(KeyProvider(wdkek, PASSWORD), Exc::InternalError);
+       BOOST_REQUIRE_NO_THROW(kp = KeyProvider(wdkek, PASSWORD));
+       BOOST_REQUIRE(!kp.isInitialized());
 }
 
 NEGATIVE_TEST_CASE(KeyProvider_garbage)
 {
-       BOOST_REQUIRE_THROW(KeyProvider(RawBuffer(sizeof(WrappedKeyAndInfo)), PASSWORD),
-                           Exc::AuthenticationFailed);
+       BOOST_REQUIRE_THROW(KeyProvider(RawBuffer(sizeof(DomainKEKAndInfo)), PASSWORD),
+                           Exc::InternalError);
 }
 
 NEGATIVE_TEST_CASE(KeyDomainKek_invalid_password)
@@ -148,7 +151,7 @@ POSITIVE_TEST_CASE(KeyGetPureDEK)
 NEGATIVE_TEST_CASE(KeyGetPureDEK_uninitialized)
 {
        KeyProvider kp;
-       RawBuffer wdek(sizeof(WrappedKeyAndInfo));
+       RawBuffer wdek(sizeof(DEKAndInfo));
 
        BOOST_REQUIRE_THROW(kp.getPureDEK(wdek), Exc::InternalError);
 }
@@ -171,7 +174,7 @@ NEGATIVE_TEST_CASE(KeyGetPureDEK_wrong_size)
 NEGATIVE_TEST_CASE(KeyGetPureDEK_garbage)
 {
        KeyProvider kp = makeDefaultKeyProvider();
-       RawBuffer wdek(sizeof(WrappedKeyAndInfo));
+       RawBuffer wdek(sizeof(DEKAndInfo));
 
        BOOST_REQUIRE_THROW(kp.getPureDEK(wdek), Exc::InternalError);
 }
@@ -180,37 +183,21 @@ POSITIVE_TEST_CASE(KeyReencrypt)
 {
        RawBuffer wdkek = makeDefaultWrappedDomainKEK();
        RawBuffer wdkek2;
+       KeyProvider keyProvider;
 
-       BOOST_REQUIRE_NO_THROW(wdkek2 = KeyProvider::reencrypt(wdkek, PASSWORD, NEW_PASSWORD));
+       BOOST_REQUIRE_NO_THROW(keyProvider = KeyProvider(wdkek, PASSWORD));
+       BOOST_REQUIRE_NO_THROW(wdkek2 = keyProvider.getWrappedDomainKEK(NEW_PASSWORD));
        BOOST_REQUIRE(!wdkek2.empty());
 }
 
-NEGATIVE_TEST_CASE(KeyReencrypt_incorrect_password)
-{
-       RawBuffer wdkek = makeDefaultWrappedDomainKEK();
-       BOOST_REQUIRE_THROW(KeyProvider::reencrypt(wdkek, INCORRECT_PASSWORD, NEW_PASSWORD),
-                           Exc::AuthenticationFailed);
-}
-
-NEGATIVE_TEST_CASE(KeyReencrypt_wrong_size)
-{
-       RawBuffer wdkek = makeDefaultWrappedDomainKEK();
-
-       wdkek.push_back(0);
-       BOOST_REQUIRE_THROW(KeyProvider::reencrypt(wdkek, PASSWORD, NEW_PASSWORD), Exc::InternalError);
-
-       wdkek.pop_back();
-       wdkek.pop_back();
-       BOOST_REQUIRE_THROW(KeyProvider::reencrypt(wdkek, PASSWORD, NEW_PASSWORD), Exc::InternalError);
-}
-
 POSITIVE_TEST_CASE(KeyGetPureDEK_after_reencrypt)
 {
        KeyProvider kp;
        RawBuffer wdek, dek, wdkek2;
        RawBuffer wdkek = makeDefaultWrappedDomainKEK();
 
-       BOOST_REQUIRE_NO_THROW(wdkek2 = KeyProvider::reencrypt(wdkek, PASSWORD, NEW_PASSWORD));
+       BOOST_REQUIRE_NO_THROW(kp = KeyProvider(wdkek, PASSWORD));
+       BOOST_REQUIRE_NO_THROW(wdkek2 = kp.getWrappedDomainKEK(NEW_PASSWORD));
        BOOST_REQUIRE(!wdkek2.empty());
 
        BOOST_REQUIRE_NO_THROW(kp = KeyProvider(wdkek2, NEW_PASSWORD));
@@ -222,59 +209,39 @@ POSITIVE_TEST_CASE(KeyGetPureDEK_after_reencrypt)
        BOOST_REQUIRE(dek.size() <= MAX_KEY_SIZE);
 }
 
-POSITIVE_TEST_CASE(wrapped_container)
+POSITIVE_TEST_CASE(dek_and_info)
 {
-       WrappedKeyAndInfoContainer wkic;
+       DEKAndInfo dai;
 
        auto salt = createRandom(20);
-       BOOST_REQUIRE_NO_THROW(wkic.setKeyInfoSalt(salt.data(), salt.size()));
-       BOOST_REQUIRE_NO_THROW(wkic.setKeyInfoClient("key_info_client"));
-
-       WrappedKeyAndInfoContainer wkic2;
-       BOOST_REQUIRE_NO_THROW(wkic2.setKeyInfo(&wkic.getWrappedKeyAndInfo().keyInfo));
-
-       BOOST_REQUIRE(wkic.getWrappedKeyAndInfo().keyInfo.keyLength ==
-                     wkic2.getWrappedKeyAndInfo().keyInfo.keyLength);
-       BOOST_REQUIRE(memcmp(wkic.getWrappedKeyAndInfo().keyInfo.salt,
-                            wkic2.getWrappedKeyAndInfo().keyInfo.salt,
-                            sizeof(wkic.getWrappedKeyAndInfo().keyInfo.salt)) == 0);
-       BOOST_REQUIRE(memcmp(wkic.getWrappedKeyAndInfo().keyInfo.client,
-                            wkic2.getWrappedKeyAndInfo().keyInfo.client,
-                            sizeof(wkic.getWrappedKeyAndInfo().keyInfo.client)) == 0);
-
-       WrappedKeyAndInfo wki;
-       wki.keyInfo.keyLength = MAX_WRAPPED_KEY_SIZE;
-       BOOST_REQUIRE_NO_THROW(wkic.setWrappedKeyAndInfo(reinterpret_cast<unsigned char*>(&wki)));
-}
+       memcpy(dai.info.salt, salt.data(), sizeof(dai.info.salt));
+       BOOST_REQUIRE_NO_THROW(dai.setKeyInfoClient("key_info_client"));
+       dai.info.keyLength = 10;
 
-NEGATIVE_TEST_CASE(wrapped_container)
-{
-       WrappedKeyAndInfoContainer wkic;
+       DEKAndInfo dai2;
+       BOOST_REQUIRE_NO_THROW(dai2.setKeyInfo(dai.info));
 
-       BOOST_REQUIRE_THROW(wkic.setKeyInfoClient("key_info_client_waaaaay_too_long"),
-                           Exc::InternalError);
-
-       WrappedKeyAndInfo wki;
-       wki.keyInfo.keyLength = MAX_WRAPPED_KEY_SIZE + 1;
-       BOOST_REQUIRE_THROW(wkic.setWrappedKeyAndInfo(reinterpret_cast<unsigned char*>(&wki)),
-                           Exc::InternalError);
-
-       // missing NULL termination in wki2.keyInfo.client
-       WrappedKeyAndInfo wki2;
-       memset(&wki2, 0x01, sizeof(WrappedKeyAndInfo));
-       BOOST_REQUIRE_THROW(wkic.setWrappedKeyAndInfo(reinterpret_cast<unsigned char*>(&wki2)),
-                           Exc::InternalError);
+       BOOST_REQUIRE(dai.info.keyLength == dai2.info.keyLength);
+       BOOST_REQUIRE(memcmp(dai.info.salt, dai2.info.salt, sizeof(dai.info.salt)) == 0);
+       BOOST_REQUIRE(memcmp(dai.info.client, dai2.info.client, sizeof(dai.info.client)) == 0);
 }
 
-POSITIVE_TEST_CASE(container)
+NEGATIVE_TEST_CASE(dek_and_info)
 {
-       KeyAndInfoContainer kic;
-       BOOST_REQUIRE_NO_THROW(kic.setKeyInfoKeyLength(10));
+       DEKAndInfo dai;
+       BOOST_REQUIRE_THROW(dai.setKeyInfoClient("key_info_client_waaaaay_too_long"),
+                           Exc::InternalError);
+
+       DEKAndInfo dai2;
+       dai2.info.keyLength = MAX_KEY_SIZE + 1;
 
-       KeyAndInfoContainer kic2;
-       BOOST_REQUIRE_NO_THROW(kic2.setKeyInfo(&kic.getKeyAndInfo().keyInfo));
+       const unsigned char *ptr = reinterpret_cast<const unsigned char *>(&dai2);
+       RawBuffer buffer(ptr, ptr + sizeof(dai2));
+       BOOST_REQUIRE_THROW(new DEKAndInfo((buffer)), Exc::InternalError);
 
-       BOOST_REQUIRE(kic.getKeyAndInfo().keyInfo.keyLength == kic2.getKeyAndInfo().keyInfo.keyLength);
+       // missing NULL termination in dai3.info.client
+       RawBuffer garbage(0x01, sizeof(DEKAndInfo));
+       BOOST_REQUIRE_THROW(new DEKAndInfo((garbage)), Exc::InternalError);
 }
 
 POSITIVE_TEST_CASE(moves)