Use common function for PKEK1&2 generation 92/198792/5
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Tue, 29 Jan 2019 10:34:18 +0000 (11:34 +0100)
committerKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Wed, 13 Feb 2019 12:37:15 +0000 (13:37 +0100)
Change-Id: Ic9c6286b3672836c2bde976adb1b79ba34793918

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

index 47425e6..2895b6c 100644 (file)
 #include <dpl/log/log.h>
 #include <string.h>
 
+#include <array>
+
+using namespace CKM;
+
 namespace {
 
 template<typename T>
-CKM::RawBuffer toRawBuffer(const T &data)
+RawBuffer toRawBuffer(const T &data)
 {
-       CKM::RawBuffer output;
+       RawBuffer output;
        const unsigned char *ptr = reinterpret_cast<const unsigned char *>(&data);
        output.assign(ptr, ptr + sizeof(T));
        return output;
@@ -32,18 +36,53 @@ CKM::RawBuffer toRawBuffer(const T &data)
 
 // You cannot use toRawBuffer template with pointers
 template<typename T>
-CKM::RawBuffer toRawBuffer(T *)
+RawBuffer toRawBuffer(T *)
 {
        class NoPointerAllowed {
                NoPointerAllowed() {}
        };
        NoPointerAllowed a;
-       return CKM::RawBuffer();
+       return RawBuffer();
 }
 
-} // anonymous namespace
+typedef std::array<uint8_t, MAX_KEY_SIZE> KeyData;
 
-using namespace CKM;
+// derives a key used for DomainKEK encryption (aka PKEK1) from random salt & user password
+KeyData makePKEK1(const KeyComponentsInfo& keyInfo, const Password &password)
+{
+       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,
+                                   PBKDF2_ITERATIONS,
+                                   key.size(),
+                                   key.data())) {
+               ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR");
+       }
+       return key;
+}
+
+// derives a key used for DB DEK encryption (aka PKEK2) from DomainKEK and user id
+KeyData makePKEK2(const uint8_t *domainKEK, const std::string &user)
+{
+       KeyData key;
+       if (!PKCS5_PBKDF2_HMAC_SHA1(user.c_str(),
+                                   user.size(),
+                                   domainKEK,
+                                   MAX_SALT_SIZE,
+                                   PBKDF2_ITERATIONS,
+                                   key.size(),
+                                   key.data())) {
+               ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR");
+       }
+       return key;
+}
+
+} // anonymous namespace
 
 WrappedKeyAndInfoContainer::WrappedKeyAndInfoContainer()
 {
@@ -167,34 +206,14 @@ KeyProvider::KeyProvider(
        WrappedKeyAndInfoContainer wkmcDKEK = WrappedKeyAndInfoContainer(
                        domainKEKInWrapForm.data());
 
-       char *concat_user_pass = NULL;
-       uint8_t PKEK1[MAX_KEY_SIZE];
-
-       concat_user_pass = concat_password_user(
-                                                  wkmcDKEK.getWrappedKeyAndInfo().keyInfo.client,
-                                                  password.c_str());
-
-       if (!PKCS5_PBKDF2_HMAC_SHA1(
-                               concat_user_pass,
-                               strlen(concat_user_pass),
-                               wkmcDKEK.getWrappedKeyAndInfo().keyInfo.salt,
-                               MAX_SALT_SIZE,
-                               PBKDF2_ITERATIONS,
-                               MAX_KEY_SIZE,
-                               PKEK1)) {
-               delete[] concat_user_pass;
-               ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR");
-       }
-
-       delete[] concat_user_pass;
+       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,
+                                                        PKEK1.data(),
                                                         wkmcDKEK.getWrappedKeyAndInfo().keyInfo.iv,
                                                         m_kmcDKEK->getKeyAndInfo().key))) {
                ThrowErr(Exc::AuthenticationFailed,
@@ -250,36 +269,16 @@ RawBuffer KeyProvider::getWrappedDomainKEK(const Password &password)
                ThrowErr(Exc::InternalError, "Object not initialized!");
 
        WrappedKeyAndInfoContainer wkmcDKEK = WrappedKeyAndInfoContainer();
-
-       char *concat_user_pass = NULL;
-       uint8_t PKEK1[MAX_KEY_SIZE];
-
-       concat_user_pass = concat_password_user(
-                                                  m_kmcDKEK->getKeyAndInfo().keyInfo.client,
-                                                  password.c_str());
-
-       if (!PKCS5_PBKDF2_HMAC_SHA1(
-                               concat_user_pass,
-                               strlen(concat_user_pass),
-                               m_kmcDKEK->getKeyAndInfo().keyInfo.salt,
-                               MAX_SALT_SIZE,
-                               PBKDF2_ITERATIONS,
-                               MAX_KEY_SIZE,
-                               PKEK1)) {
-               delete[] concat_user_pass;
-               ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR");
-       }
-
-       delete[] concat_user_pass;
-
        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,
+                                                                       PKEK1.data(),
                                                                        m_kmcDKEK->getKeyAndInfo().keyInfo.iv,
                                                                        wkmcDKEK.getWrappedKeyAndInfo().wrappedKey,
                                                                        wkmcDKEK.getWrappedKeyAndInfo().keyInfo.tag)))
@@ -309,24 +308,15 @@ RawBuffer KeyProvider::getPureDEK(const RawBuffer &DEKInWrapForm)
        WrappedKeyAndInfoContainer wkmcDEK = WrappedKeyAndInfoContainer(
                        DEKInWrapForm.data());
 
-       uint8_t PKEK2[MAX_KEY_SIZE];
-       int keyLength;
-
-       if (!PKCS5_PBKDF2_HMAC_SHA1(
-                               wkmcDEK.getWrappedKeyAndInfo().keyInfo.client,
-                               strlen(wkmcDEK.getWrappedKeyAndInfo().keyInfo.client),
-                               m_kmcDKEK->getKeyAndInfo().key,
-                               MAX_SALT_SIZE,
-                               PBKDF2_ITERATIONS,
-                               MAX_KEY_SIZE,
-                               PKEK2))
-               ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR");
+       KeyData PKEK2 = makePKEK2(m_kmcDKEK->getKeyAndInfo().key,
+                                 wkmcDEK.getWrappedKeyAndInfo().keyInfo.client);
 
+       int keyLength;
        if (0 > (keyLength = decryptAes256Gcm(
                                                         wkmcDEK.getWrappedKeyAndInfo().wrappedKey,
                                                         wkmcDEK.getWrappedKeyAndInfo().keyInfo.keyLength,
                                                         wkmcDEK.getWrappedKeyAndInfo().keyInfo.tag,
-                                                        PKEK2,
+                                                        PKEK2.data(),
                                                         wkmcDEK.getWrappedKeyAndInfo().keyInfo.iv,
                                                         kmcDEK.getKeyAndInfo().key)))
                ThrowErr(Exc::InternalError,
@@ -353,28 +343,19 @@ RawBuffer KeyProvider::generateDEK(const ClientId &client)
        else
                resized_client = client.substr(0, MAX_CLIENT_ID_SIZE - 1);
 
-       uint8_t key[MAX_KEY_SIZE], PKEK2[MAX_KEY_SIZE];
+       uint8_t key[MAX_KEY_SIZE];
 
        if (!RAND_bytes(key, m_kmcDKEK->getKeyAndInfo().keyInfo.keyLength) ||
                        !RAND_bytes(wkmcDEK.getWrappedKeyAndInfo().keyInfo.iv, MAX_IV_SIZE))
                ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR");
 
-       if (!PKCS5_PBKDF2_HMAC_SHA1(
-                               resized_client.c_str(),
-                               strlen(resized_client.c_str()),
-                               m_kmcDKEK->getKeyAndInfo().key,
-                               MAX_SALT_SIZE,
-                               PBKDF2_ITERATIONS,
-                               MAX_KEY_SIZE,
-                               PKEK2))
-               ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR");
+       KeyData PKEK2 = makePKEK2(m_kmcDKEK->getKeyAndInfo().key, resized_client);
 
        int wrappedKeyLength;
-
        if (0 > (wrappedKeyLength = encryptAes256Gcm(
                                                                        key,
                                                                        m_kmcDKEK->getKeyAndInfo().keyInfo.keyLength,
-                                                                       PKEK2,
+                                                                       PKEK2.data(),
                                                                        wkmcDEK.getWrappedKeyAndInfo().keyInfo.iv,
                                                                        wkmcDEK.getWrappedKeyAndInfo().wrappedKey,
                                                                        wkmcDEK.getWrappedKeyAndInfo().keyInfo.tag)))
@@ -405,34 +386,14 @@ RawBuffer KeyProvider::reencrypt(
        WrappedKeyAndInfoContainer wkmcNewDKEK = WrappedKeyAndInfoContainer();
        KeyAndInfoContainer kmcDKEK = KeyAndInfoContainer();
 
-       char *concat_user_pass = NULL;
-       uint8_t PKEK1[MAX_KEY_SIZE];
-       int keyLength = 0;
-
-
-       concat_user_pass = concat_password_user(
-                                                  wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo.client,
-                                                  oldPass.c_str());
-
-       if (!PKCS5_PBKDF2_HMAC_SHA1(
-                               concat_user_pass,
-                               strlen(concat_user_pass),
-                               wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo.salt,
-                               MAX_SALT_SIZE,
-                               PBKDF2_ITERATIONS,
-                               MAX_KEY_SIZE,
-                               PKEK1)) {
-               delete[] concat_user_pass;
-               ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR");
-       }
-
-       delete[] concat_user_pass;
+       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,
+                                                        PKEK1.data(),
                                                         wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo.iv,
                                                         kmcDKEK.getKeyAndInfo().key)))
                ThrowErr(Exc::AuthenticationFailed, "Incorrect Old Password ");
@@ -440,31 +401,15 @@ RawBuffer KeyProvider::reencrypt(
        kmcDKEK.setKeyInfo(&(wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo));
        kmcDKEK.setKeyInfoKeyLength((unsigned int)keyLength);
 
-       concat_user_pass = concat_password_user(
-                                                  kmcDKEK.getKeyAndInfo().keyInfo.client,
-                                                  newPass.c_str());
-
-       if (!PKCS5_PBKDF2_HMAC_SHA1(
-                               concat_user_pass,
-                               strlen(concat_user_pass),
-                               kmcDKEK.getKeyAndInfo().keyInfo.salt,
-                               MAX_SALT_SIZE,
-                               PBKDF2_ITERATIONS,
-                               MAX_KEY_SIZE,
-                               PKEK1)) {
-               delete[] concat_user_pass;
-               ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR");
-       }
-
-       delete[] concat_user_pass;
+       PKEK1 = makePKEK1(wkmcNewDKEK.getWrappedKeyAndInfo().keyInfo, newPass);
 
-       int wrappedKeyLength = 0;
        wkmcNewDKEK.setKeyInfo(&(kmcDKEK.getKeyAndInfo().keyInfo));
 
+       int wrappedKeyLength = 0;
        if (0 > (wrappedKeyLength = encryptAes256Gcm(
                                                                        kmcDKEK.getKeyAndInfo().key,
                                                                        kmcDKEK.getKeyAndInfo().keyInfo.keyLength,
-                                                                       PKEK1,
+                                                                       PKEK1.data(),
                                                                        kmcDKEK.getKeyAndInfo().keyInfo.iv,
                                                                        wkmcNewDKEK.getWrappedKeyAndInfo().wrappedKey,
                                                                        wkmcNewDKEK.getWrappedKeyAndInfo().keyInfo.tag)))
@@ -477,41 +422,27 @@ RawBuffer KeyProvider::reencrypt(
        return toRawBuffer(wkmcNewDKEK.getWrappedKeyAndInfo());
 }
 
-
 RawBuffer KeyProvider::generateDomainKEK(
        const std::string &user,
        const Password &userPassword)
 {
        WrappedKeyAndInfoContainer wkmcDKEK = WrappedKeyAndInfoContainer();
-       uint8_t key[MAX_KEY_SIZE], PKEK1[MAX_KEY_SIZE];
+       uint8_t key[MAX_KEY_SIZE];
+       int wrappedKeyLength;
+
+       wkmcDKEK.setKeyInfoClient(user);
 
        if (!RAND_bytes(wkmcDKEK.getWrappedKeyAndInfo().keyInfo.salt, MAX_SALT_SIZE) ||
                        !RAND_bytes(key, MAX_KEY_SIZE) ||
                        !RAND_bytes(wkmcDKEK.getWrappedKeyAndInfo().keyInfo.iv, MAX_IV_SIZE))
                ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR");
 
-       int wrappedKeyLength;
-       char *concat_user_pass = NULL;
-       concat_user_pass = concat_password_user(user.c_str(), userPassword.c_str());
-
-       if (!PKCS5_PBKDF2_HMAC_SHA1(
-                               concat_user_pass,
-                               strlen(concat_user_pass),
-                               wkmcDKEK.getWrappedKeyAndInfo().keyInfo.salt,
-                               MAX_SALT_SIZE,
-                               PBKDF2_ITERATIONS,
-                               MAX_KEY_SIZE,
-                               PKEK1)) {
-               delete[] concat_user_pass;
-               ThrowErr(Exc::InternalError, "OPENSSL_ENGINED_ERROR");
-       }
-
-       delete[] concat_user_pass;
+       KeyData PKEK1 = makePKEK1(wkmcDKEK.getWrappedKeyAndInfo().keyInfo, userPassword);
 
        if (0 > (wrappedKeyLength = encryptAes256Gcm(
                                                                        key,
-                                                                       MAX_KEY_SIZE,
-                                                                       PKEK1,
+                                                                       sizeof(key),
+                                                                       PKEK1.data(),
                                                                        wkmcDKEK.getWrappedKeyAndInfo().keyInfo.iv,
                                                                        wkmcDKEK.getWrappedKeyAndInfo().wrappedKey,
                                                                        wkmcDKEK.getWrappedKeyAndInfo().keyInfo.tag)))
@@ -621,16 +552,3 @@ int KeyProvider::decryptAes256Gcm(const unsigned char *ciphertext,
                return -1;
        }
 }
-
-char *KeyProvider::concat_password_user(const char *user, const char *password)
-{
-       std::string result(password);
-       result += user;
-
-       if (strlen(user) > MAX_CLIENT_ID_SIZE - 1)
-               result.resize(strlen(password) + MAX_CLIENT_ID_SIZE - 1);
-
-       char *ret = new char[result.size() + 1];
-       memcpy(ret, result.c_str(), result.size() + 1);
-       return ret;
-}
index bcc999f..5f6e0cb 100644 (file)
@@ -183,10 +183,6 @@ private:
                const unsigned char *key,
                const unsigned char *iv,
                unsigned char *plaintext);
-
-       static char *concat_password_user(
-               const char *user,
-               const char *password);
 };
 
 } // namespace CKM