Add helpers for domain KEK encryption/decryption 95/198795/5
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Tue, 29 Jan 2019 14:58:55 +0000 (15:58 +0100)
committerKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Wed, 13 Feb 2019 12:37:15 +0000 (13:37 +0100)
Change-Id: I048649f8a9a3450f6cefcbd9d2d75c8445f46277

src/manager/service/key-provider.cpp
src/manager/service/key-provider.h

index aea5c9b..8168fda 100644 (file)
@@ -162,6 +162,46 @@ KeyData makePKEK2(const uint8_t *domainKEK, const std::string &user)
        return key;
 }
 
+void unwrapDomainKEK(const RawBuffer &wrappedDomainKEKbuffer,
+                     const Password &password,
+                     KeyAndInfoContainer &domainKEK)
+{
+       WrappedKeyAndInfoContainer wrappedDomainKEK(wrappedDomainKEKbuffer.data());
+
+       KeyData PKEK1 = makePKEK1(wrappedDomainKEK.getWrappedKeyAndInfo().keyInfo, password);
+
+       int keyLength;
+       if (0 > (keyLength = decryptAes256Gcm(wrappedDomainKEK.getWrappedKeyAndInfo().wrappedKey,
+                                             wrappedDomainKEK.getWrappedKeyAndInfo().keyInfo.keyLength,
+                                             wrappedDomainKEK.getWrappedKeyAndInfo().keyInfo.tag,
+                                             PKEK1.data(),
+                                             wrappedDomainKEK.getWrappedKeyAndInfo().keyInfo.iv,
+                                             domainKEK.getKeyAndInfo().key)))
+               ThrowErr(Exc::AuthenticationFailed, "DomainKEK decryption failed");
+
+       domainKEK.setKeyInfo(&(wrappedDomainKEK.getWrappedKeyAndInfo().keyInfo));
+       domainKEK.setKeyInfoKeyLength(static_cast<unsigned int>(keyLength));
+}
+
+RawBuffer wrapDomainKEK(KeyAndInfoContainer &domainKEK, const Password &password)
+{
+       KeyData PKEK1 = makePKEK1(domainKEK.getKeyAndInfo().keyInfo, password);
+
+       WrappedKeyAndInfoContainer wrappedDomainKEK = WrappedKeyAndInfoContainer();
+       wrappedDomainKEK.setKeyInfo(&(domainKEK.getKeyAndInfo().keyInfo));
+
+       int wrappedLength;
+       if (0 > (wrappedLength = encryptAes256Gcm(domainKEK.getKeyAndInfo().key,
+                                                 domainKEK.getKeyAndInfo().keyInfo.keyLength,
+                                                 PKEK1.data(),
+                                                 domainKEK.getKeyAndInfo().keyInfo.iv,
+                                                 wrappedDomainKEK.getWrappedKeyAndInfo().wrappedKey,
+                                                 wrappedDomainKEK.getWrappedKeyAndInfo().keyInfo.tag)))
+               ThrowErr(Exc::InternalError, "DomainKEK encryption failed");
+
+       wrappedDomainKEK.setKeyInfoKeyLength(static_cast<unsigned int>(wrappedLength));
+       return toRawBuffer(wrappedDomainKEK.getWrappedKeyAndInfo());
+}
 
 template <size_t N>
 bool randomize(uint8_t (&array)[N])
@@ -268,7 +308,7 @@ KeyAndInfoContainer::~KeyAndInfoContainer()
 }
 
 KeyProvider::KeyProvider() :
-       m_kmcDKEK(NULL),
+       m_domainKEK(NULL),
        m_isInitialized(false)
 {
        LogDebug("Created empty KeyProvider");
@@ -277,7 +317,7 @@ KeyProvider::KeyProvider() :
 KeyProvider::KeyProvider(
        const RawBuffer &domainKEKInWrapForm,
        const Password &password) :
-       m_kmcDKEK(new KeyAndInfoContainer()),
+       m_domainKEK(new KeyAndInfoContainer()),
        m_isInitialized(true)
 {
        if (!m_isInitialized)
@@ -290,25 +330,7 @@ KeyProvider::KeyProvider(
                                 "buffer doesn't have proper size to store WrappedKeyAndInfo in KeyProvider Constructor");
        }
 
-       WrappedKeyAndInfoContainer wkmcDKEK = WrappedKeyAndInfoContainer(
-                       domainKEKInWrapForm.data());
-
-       KeyData PKEK1 = makePKEK1(wkmcDKEK.getWrappedKeyAndInfo().keyInfo, password);
-
-       int keyLength;
-       if (0 > (keyLength = decryptAes256Gcm(
-                                                        wkmcDKEK.getWrappedKeyAndInfo().wrappedKey,
-                                                        wkmcDKEK.getWrappedKeyAndInfo().keyInfo.keyLength,
-                                                        wkmcDKEK.getWrappedKeyAndInfo().keyInfo.tag,
-                                                        PKEK1.data(),
-                                                        wkmcDKEK.getWrappedKeyAndInfo().keyInfo.iv,
-                                                        m_kmcDKEK->getKeyAndInfo().key))) {
-               ThrowErr(Exc::AuthenticationFailed,
-                                "VerifyDomainKEK failed in KeyProvider Constructor");
-       }
-
-       m_kmcDKEK->setKeyInfo(&(wkmcDKEK.getWrappedKeyAndInfo().keyInfo));
-       m_kmcDKEK->setKeyInfoKeyLength((unsigned int)keyLength);
+       unwrapDomainKEK(domainKEKInWrapForm, password, *m_domainKEK);
 }
 
 KeyProvider &KeyProvider::operator=(KeyProvider &&second)
@@ -319,9 +341,9 @@ KeyProvider &KeyProvider::operator=(KeyProvider &&second)
                return *this;
 
        m_isInitialized = second.m_isInitialized;
-       m_kmcDKEK = second.m_kmcDKEK;
+       m_domainKEK = second.m_domainKEK;
        second.m_isInitialized = false;
-       second.m_kmcDKEK = NULL;
+       second.m_domainKEK = NULL;
        return *this;
 }
 
@@ -329,9 +351,9 @@ KeyProvider::KeyProvider(KeyProvider &&second)
 {
        LogDebug("Moving KeyProvider");
        m_isInitialized = second.m_isInitialized;
-       m_kmcDKEK = second.m_kmcDKEK;
+       m_domainKEK = second.m_domainKEK;
        second.m_isInitialized = false;
-       second.m_kmcDKEK = NULL;
+       second.m_domainKEK = NULL;
 }
 
 bool KeyProvider::isInitialized()
@@ -345,9 +367,9 @@ RawBuffer KeyProvider::getPureDomainKEK()
                ThrowErr(Exc::InternalError, "Object not initialized!");
 
        // TODO secure
-       return RawBuffer(m_kmcDKEK->getKeyAndInfo().key,
-                                        (m_kmcDKEK->getKeyAndInfo().key) +
-                                        m_kmcDKEK->getKeyAndInfo().keyInfo.keyLength);
+       return RawBuffer(m_domainKEK->getKeyAndInfo().key,
+                                        (m_domainKEK->getKeyAndInfo().key) +
+                                        m_domainKEK->getKeyAndInfo().keyInfo.keyLength);
 }
 
 RawBuffer KeyProvider::getWrappedDomainKEK(const Password &password)
@@ -355,26 +377,7 @@ RawBuffer KeyProvider::getWrappedDomainKEK(const Password &password)
        if (!m_isInitialized)
                ThrowErr(Exc::InternalError, "Object not initialized!");
 
-       WrappedKeyAndInfoContainer wkmcDKEK = WrappedKeyAndInfoContainer();
-       wkmcDKEK.setKeyInfo(&(m_kmcDKEK->getKeyAndInfo().keyInfo));
-
-       KeyData PKEK1 = makePKEK1(wkmcDKEK.getWrappedKeyAndInfo().keyInfo, password);
-
-       int wrappedKeyLength;
-
-       if (0 > (wrappedKeyLength = encryptAes256Gcm(
-                                                                       m_kmcDKEK->getKeyAndInfo().key,
-                                                                       m_kmcDKEK->getKeyAndInfo().keyInfo.keyLength,
-                                                                       PKEK1.data(),
-                                                                       m_kmcDKEK->getKeyAndInfo().keyInfo.iv,
-                                                                       wkmcDKEK.getWrappedKeyAndInfo().wrappedKey,
-                                                                       wkmcDKEK.getWrappedKeyAndInfo().keyInfo.tag)))
-               ThrowErr(Exc::InternalError, "WrapDKEK Failed in KeyProvider::getDomainKEK");
-
-       wkmcDKEK.setKeyInfoKeyLength((unsigned int)wrappedKeyLength);
-
-       LogDebug("getDomainKEK(password) Success");
-       return toRawBuffer(wkmcDKEK.getWrappedKeyAndInfo());
+       return wrapDomainKEK(*m_domainKEK, password);
 }
 
 
@@ -395,7 +398,7 @@ RawBuffer KeyProvider::getPureDEK(const RawBuffer &DEKInWrapForm)
        WrappedKeyAndInfoContainer wkmcDEK = WrappedKeyAndInfoContainer(
                        DEKInWrapForm.data());
 
-       KeyData PKEK2 = makePKEK2(m_kmcDKEK->getKeyAndInfo().key,
+       KeyData PKEK2 = makePKEK2(m_domainKEK->getKeyAndInfo().key,
                                  wkmcDEK.getWrappedKeyAndInfo().keyInfo.client);
 
        int keyLength;
@@ -435,16 +438,15 @@ RawBuffer KeyProvider::generateDEK(const ClientId &client)
        if (!randomize(key) || !randomize(wkmcDEK.getWrappedKeyAndInfo().keyInfo.iv))
                ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR");
 
-       KeyData PKEK2 = makePKEK2(m_kmcDKEK->getKeyAndInfo().key, resized_client);
+       KeyData PKEK2 = makePKEK2(m_domainKEK->getKeyAndInfo().key, resized_client);
 
        int wrappedKeyLength;
-       if (0 > (wrappedKeyLength = encryptAes256Gcm(
-                                                                       key,
-                                                                       m_kmcDKEK->getKeyAndInfo().keyInfo.keyLength,
-                                                                       PKEK2.data(),
-                                                                       wkmcDEK.getWrappedKeyAndInfo().keyInfo.iv,
-                                                                       wkmcDEK.getWrappedKeyAndInfo().wrappedKey,
-                                                                       wkmcDEK.getWrappedKeyAndInfo().keyInfo.tag)))
+       if (0 > (wrappedKeyLength = encryptAes256Gcm(key,
+                                                    m_domainKEK->getKeyAndInfo().keyInfo.keyLength,
+                                                    PKEK2.data(),
+                                                    wkmcDEK.getWrappedKeyAndInfo().keyInfo.iv,
+                                                    wkmcDEK.getWrappedKeyAndInfo().wrappedKey,
+                                                    wkmcDEK.getWrappedKeyAndInfo().keyInfo.tag)))
                ThrowErr(Exc::InternalError, "GenerateDEK Failed in KeyProvider::generateDEK");
 
        wkmcDEK.setKeyInfoKeyLength((unsigned int)wrappedKeyLength);
@@ -467,45 +469,9 @@ RawBuffer KeyProvider::reencrypt(
                                 "WrappedKeyAndInfo in KeyProvider::reencrypt");
        }
 
-       WrappedKeyAndInfoContainer wkmcOldDKEK = WrappedKeyAndInfoContainer(
-                               domainKEKInWrapForm.data());
-       WrappedKeyAndInfoContainer wkmcNewDKEK = WrappedKeyAndInfoContainer();
-       KeyAndInfoContainer kmcDKEK = KeyAndInfoContainer();
-
-       KeyData PKEK1 = makePKEK1(wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo, oldPass);
-
-       int keyLength = 0;
-       if (0 > (keyLength = decryptAes256Gcm(
-                                                        wkmcOldDKEK.getWrappedKeyAndInfo().wrappedKey,
-                                                        wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo.keyLength,
-                                                        wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo.tag,
-                                                        PKEK1.data(),
-                                                        wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo.iv,
-                                                        kmcDKEK.getKeyAndInfo().key)))
-               ThrowErr(Exc::AuthenticationFailed, "Incorrect Old Password ");
-
-       kmcDKEK.setKeyInfo(&(wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo));
-       kmcDKEK.setKeyInfoKeyLength((unsigned int)keyLength);
-
-       PKEK1 = makePKEK1(wkmcNewDKEK.getWrappedKeyAndInfo().keyInfo, newPass);
-
-       wkmcNewDKEK.setKeyInfo(&(kmcDKEK.getKeyAndInfo().keyInfo));
-
-       int wrappedKeyLength = 0;
-       if (0 > (wrappedKeyLength = encryptAes256Gcm(
-                                                                       kmcDKEK.getKeyAndInfo().key,
-                                                                       kmcDKEK.getKeyAndInfo().keyInfo.keyLength,
-                                                                       PKEK1.data(),
-                                                                       kmcDKEK.getKeyAndInfo().keyInfo.iv,
-                                                                       wkmcNewDKEK.getWrappedKeyAndInfo().wrappedKey,
-                                                                       wkmcNewDKEK.getWrappedKeyAndInfo().keyInfo.tag)))
-               ThrowErr(Exc::InternalError,
-                                "UpdateDomainKEK in KeyProvider::reencrypt Failed");
-
-       wkmcNewDKEK.setKeyInfoKeyLength((unsigned int)wrappedKeyLength);
-
-       LogDebug("reencrypt SUCCESS");
-       return toRawBuffer(wkmcNewDKEK.getWrappedKeyAndInfo());
+       KeyAndInfoContainer domainKEK;
+       unwrapDomainKEK(domainKEKInWrapForm, oldPass, domainKEK);
+       return wrapDomainKEK(domainKEK, newPass);
 }
 
 RawBuffer KeyProvider::generateDomainKEK(
@@ -513,34 +479,23 @@ RawBuffer KeyProvider::generateDomainKEK(
        const Password &userPassword)
 {
        WrappedKeyAndInfoContainer wkmcDKEK = WrappedKeyAndInfoContainer();
-       uint8_t key[MAX_KEY_SIZE];
-       int wrappedKeyLength;
 
-       wkmcDKEK.setKeyInfoClient(user);
+       KeyAndInfoContainer domainKEK;
 
-       if (!randomize(wkmcDKEK.getWrappedKeyAndInfo().keyInfo.salt) ||
-           !randomize(key) ||
-           !randomize(wkmcDKEK.getWrappedKeyAndInfo().keyInfo.iv)) {
+       if (!randomize(domainKEK.getKeyAndInfo().keyInfo.salt) ||
+               !randomize(domainKEK.getKeyAndInfo().key) ||
+           !randomize(domainKEK.getKeyAndInfo().keyInfo.iv)) {
                ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR");
        }
 
-       KeyData PKEK1 = makePKEK1(wkmcDKEK.getWrappedKeyAndInfo().keyInfo, userPassword);
+       domainKEK.setKeyInfoKeyLength(sizeof(domainKEK.getKeyAndInfo().key));
 
-       if (0 > (wrappedKeyLength = encryptAes256Gcm(
-                                                                       key,
-                                                                       sizeof(key),
-                                                                       PKEK1.data(),
-                                                                       wkmcDKEK.getWrappedKeyAndInfo().keyInfo.iv,
-                                                                       wkmcDKEK.getWrappedKeyAndInfo().wrappedKey,
-                                                                       wkmcDKEK.getWrappedKeyAndInfo().keyInfo.tag)))
-               ThrowErr(Exc::InternalError,
-                                "GenerateDomainKEK Failed in KeyProvider::generateDomainKEK");
-
-       wkmcDKEK.setKeyInfoKeyLength((unsigned int)wrappedKeyLength);
-       wkmcDKEK.setKeyInfoClient(user);
+       if (user.size() >= sizeof(domainKEK.getKeyAndInfo().keyInfo.client)) {
+               ThrowErr(Exc::InternalError, "Client name too long");
+       }
+       strcpy(domainKEK.getKeyAndInfo().keyInfo.client, user.c_str());
 
-       LogDebug("generateDomainKEK Success");
-       return toRawBuffer(wkmcDKEK.getWrappedKeyAndInfo());
+       return wrapDomainKEK(domainKEK, userPassword);
 }
 
 int KeyProvider::initializeLibrary()
index ed47b58..23523fa 100644 (file)
@@ -165,7 +165,7 @@ public:
 
 private:
        // KeyAndInfoContainer class
-       std::shared_ptr<KeyAndInfoContainer> m_kmcDKEK;
+       std::shared_ptr<KeyAndInfoContainer> m_domainKEK;
        bool m_isInitialized;
 };