Remove dependency to ckm-key-provider.h.
authorkyungwook tak <k.tak@samsung.com>
Fri, 12 Sep 2014 07:55:12 +0000 (16:55 +0900)
committerBartlomiej Grzelewski <b.grzelewski@samsung.com>
Fri, 12 Sep 2014 13:03:39 +0000 (15:03 +0200)
This commit removes dependency to device specific code.

Change-Id: If6443737e844feb0c9d0eb3a17693876b1a870da
Signed-off-by: kyungwook tak <k.tak@samsung.com>
CMakeLists.txt
packaging/key-manager.spec
src/CMakeLists.txt
src/manager/CMakeLists.txt
src/manager/service/key-provider.cpp [new file with mode: 0644]
src/manager/service/key-provider.h
tests/CMakeLists.txt

index ec95fb4..4a7090c 100644 (file)
@@ -62,7 +62,6 @@ SET(TARGET_KEY_MANAGER "key-manager")
 SET(TARGET_KEY_MANAGER_CLIENT "key-manager-client")
 SET(TARGET_KEY_MANAGER_CONTROL_CLIENT "key-manager-control-client")
 SET(TARGET_KEY_MANAGER_COMMON "key-manager-commons")
-SET(TARGET_KEY_MANAGER_KEY_PROVIDER "key-manager-key-provider")
 SET(TARGET_LISTENER "key-manager-listener")
 
 SET(TARGET_TEST_MERGED "ckm-tests-internal")
index 8cbdd29..55a935d 100644 (file)
@@ -105,10 +105,6 @@ ln -s ../central-key-manager-api-ocsp.socket %{buildroot}/usr/lib/systemd/system
 rm -rf %{buildroot}
 
 %post
-%if "%{sec_product_feature_security_mdfpp_enable}" == "1"
-rm %{_libdir}/libkey-manager-key-provider.so.1.0.0
-ln -s %{_libdir}/libskmm.so %{_libdir}/libkey-manager-key-provider.so.1.0.0
-%endif
 systemctl daemon-reload
 if [ $1 = 1 ]; then
     # installation
@@ -164,7 +160,6 @@ fi
 %manifest key-manager.manifest
 %attr(755,root,root) /usr/bin/key-manager
 %{_libdir}/libkey-manager-commons.so*
-%{_libdir}/libkey-manager-key-provider.so*
 %attr(-,root,root) /usr/lib/systemd/system/multi-user.target.wants/central-key-manager.service
 %attr(-,root,root) /usr/lib/systemd/system/central-key-manager.service
 %attr(-,root,root) /usr/lib/systemd/system/central-key-manager.target
index 38b6907..80d484e 100644 (file)
@@ -54,7 +54,6 @@ ADD_EXECUTABLE(${TARGET_KEY_MANAGER} ${KEY_MANAGER_SOURCES})
 TARGET_LINK_LIBRARIES(${TARGET_KEY_MANAGER}
     ${KEY_MANAGER_DEP_LIBRARIES}
     ${TARGET_KEY_MANAGER_COMMON}
-    ${TARGET_KEY_MANAGER_KEY_PROVIDER}
     )
 
 ################################################################################
index 274c130..f5e2330 100644 (file)
@@ -6,11 +6,6 @@ PKG_CHECK_MODULES(COMMON_DEP
     libsmack
     libcrypto
     )
-PKG_CHECK_MODULES(KEY_PROVIDER_DEP
-    dlog
-    openssl
-    REQUIRED
-    )
 
 SET(KEY_MANAGER_COMMON_VERSION_MAJOR 1)
 SET(KEY_MANAGER_COMMON_VERSION ${KEY_MANAGER_COMMON_VERSION_MAJOR}.0.1)
@@ -54,7 +49,7 @@ INCLUDE_DIRECTORIES(
     ${COMMON_PATH}/dpl/log/include
     ${COMMON_PATH}/dpl/db/include
     ${COMMON_PATH}/sqlcipher
-       ${COMMON_PATH}/service
+    ${COMMON_PATH}/service
     )
 
 ADD_LIBRARY(${TARGET_KEY_MANAGER_COMMON} SHARED ${COMMON_SOURCES})
@@ -71,28 +66,6 @@ TARGET_LINK_LIBRARIES(${TARGET_KEY_MANAGER_COMMON}
     ${COMMON_DEP_LIBRARIES}
     )
 
-###########################################################################
-SET(KEY_PROVIDER_SOURCES
-    ${COMMON_PATH}/service/ckm-key-provider-dummy.c
-    )
-
-ADD_LIBRARY(${TARGET_KEY_MANAGER_KEY_PROVIDER} SHARED ${KEY_PROVIDER_SOURCES})
-SET_TARGET_PROPERTIES(
-    ${TARGET_KEY_MANAGER_KEY_PROVIDER}
-    PROPERTIES
-        COMPILE_FLAGS "-fPIC -c"
-        SOVERSION 1.0.0
-        VERSION 1.0.0
-    )
-TARGET_LINK_LIBRARIES(${TARGET_KEY_MANAGER_KEY_PROVIDER}
-    ${KEY_PROVIDER_DEP_LIBRARIES}
-    )
-
-##########################################################################
-
 ################################################################################
 
 INSTALL(TARGETS ${TARGET_KEY_MANAGER_COMMON} DESTINATION lib)
-
-INSTALL(TARGETS ${TARGET_KEY_MANAGER_KEY_PROVIDER} DESTINATION lib)
-
diff --git a/src/manager/service/key-provider.cpp b/src/manager/service/key-provider.cpp
new file mode 100644 (file)
index 0000000..d50e131
--- /dev/null
@@ -0,0 +1,653 @@
+#include <key-provider.h>
+#include <dpl/log/log.h>
+
+namespace {
+
+template<typename T>
+CKM::RawBuffer toRawBuffer(const T &data)
+{
+    CKM::RawBuffer output;
+    const unsigned char *ptr = reinterpret_cast<const unsigned char*>(&data);
+    output.assign(ptr, ptr + sizeof(T));
+    return output;
+}
+
+// You cannot use toRawBuffer template with pointers
+template<typename T>
+CKM::RawBuffer toRawBuffer(T *)
+{
+    class NoPointerAllowed { NoPointerAllowed(){} };
+    NoPointerAllowed a;
+    return CKM::RawBuffer();
+}
+
+} // anonymous namespace
+
+using namespace CKM;
+
+WrappedKeyAndInfoContainer::WrappedKeyAndInfoContainer()
+{
+    wrappedKeyAndInfo = new WrappedKeyAndInfo;
+    memset(wrappedKeyAndInfo, 0, sizeof(WrappedKeyAndInfo));
+}
+
+WrappedKeyAndInfoContainer::WrappedKeyAndInfoContainer(const unsigned char *data)
+{
+    wrappedKeyAndInfo = new WrappedKeyAndInfo;
+    memcpy(wrappedKeyAndInfo, data, sizeof(WrappedKeyAndInfo));
+}
+
+WrappedKeyAndInfo& WrappedKeyAndInfoContainer::getWrappedKeyAndInfo()
+{
+    return *wrappedKeyAndInfo;
+}
+
+void WrappedKeyAndInfoContainer::setKeyInfoKeyLength(const unsigned int length){
+    wrappedKeyAndInfo->keyInfo.keyLength = length;
+}
+
+void WrappedKeyAndInfoContainer::setKeyInfoLabel(const std::string label)
+{
+    strncpy(
+        wrappedKeyAndInfo->keyInfo.label,
+        label.c_str(),
+        MAX_LABEL_SIZE);
+}
+
+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()
+{
+    delete wrappedKeyAndInfo;
+}
+
+KeyAndInfoContainer::KeyAndInfoContainer()
+{
+    keyAndInfo = new KeyAndInfo;
+    memset(keyAndInfo, 0, sizeof(KeyAndInfo));
+}
+
+KeyAndInfoContainer::KeyAndInfoContainer(const unsigned char *data)
+{
+    keyAndInfo = new KeyAndInfo;
+    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
+    char *ptr = reinterpret_cast<char*>(keyAndInfo);
+    for (size_t size = 0; size < sizeof(KeyAndInfo); ++size)
+        ptr[size] = 0;
+    // verification
+    for (size_t size = 0; size < sizeof(KeyAndInfo); ++size) {
+        if (0 != ptr[size]) {
+            delete keyAndInfo;
+            ThrowMsg(Exception::Base, "KeyAndInfo in KeyAndInfoContainer "
+                "was not destroyed!");
+        }
+    }
+    delete keyAndInfo;
+}
+
+KeyProvider::KeyProvider()
+    : m_kmcDKEK(NULL)
+    , m_isInitialized(false)
+{
+    LogDebug("Created empty KeyProvider");
+}
+
+KeyProvider::KeyProvider(
+    const RawBuffer &domainKEKInWrapForm,
+    const Password &password)
+    : m_kmcDKEK(new KeyAndInfoContainer())
+    , m_isInitialized(true)
+{
+    if (!m_isInitialized) {
+        ThrowMsg(Exception::InitFailed, "Object not initialized!. Should not happened");
+    }
+    if (domainKEKInWrapForm.size() != sizeof(WrappedKeyAndInfo)) {
+        LogError("input size:" << domainKEKInWrapForm.size()
+            << " Expected: " << sizeof(WrappedKeyAndInfo));
+        ThrowMsg(Exception::InputParamError, "buffer doesn't have proper size to store WrappedKeyAndInfo in KeyProvider Constructor");
+    }
+
+    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.label,
+        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;
+        ThrowMsg(Exception::OpensslEngineError, "OPENSSL_ENGINE_ERROR");
+    }
+
+    delete[] concat_user_pass;
+
+    int keyLength;
+
+    if (0 > (keyLength = decryptAes256Gcm(
+        wkmcDKEK.getWrappedKeyAndInfo().wrappedKey,
+        wkmcDKEK.getWrappedKeyAndInfo().keyInfo.keyLength,
+        wkmcDKEK.getWrappedKeyAndInfo().keyInfo.tag,
+        PKEK1,
+        wkmcDKEK.getWrappedKeyAndInfo().keyInfo.iv,
+        m_kmcDKEK->getKeyAndInfo().key))) {
+
+        ThrowMsg(Exception::PassWordError, "VerifyDomainKEK failed in KeyProvider Constructor");
+    }
+
+    m_kmcDKEK->setKeyInfo(&(wkmcDKEK.getWrappedKeyAndInfo().keyInfo));
+    m_kmcDKEK->setKeyInfoKeyLength((unsigned int)keyLength);
+}
+
+KeyProvider& KeyProvider::operator=(KeyProvider &&second)
+{
+    LogDebug("Moving KeyProvider");
+    if (this == &second)
+        return *this;
+    m_isInitialized = second.m_isInitialized;
+    m_kmcDKEK = second.m_kmcDKEK;
+    second.m_isInitialized = false;
+    second.m_kmcDKEK = NULL;
+    return *this;
+}
+
+KeyProvider::KeyProvider(KeyProvider &&second)
+{
+    LogDebug("Moving KeyProvider");
+    m_isInitialized = second.m_isInitialized;
+    m_kmcDKEK = second.m_kmcDKEK;
+    second.m_isInitialized = false;
+    second.m_kmcDKEK = NULL;
+}
+
+bool KeyProvider::isInitialized()
+{
+    return m_isInitialized;
+}
+
+RawBuffer KeyProvider::getPureDomainKEK()
+{
+    if (!m_isInitialized) {
+        ThrowMsg(Exception::InitFailed, "Object not initialized!");
+    }
+
+    // TODO secure
+    return RawBuffer(m_kmcDKEK->getKeyAndInfo().key, (m_kmcDKEK->getKeyAndInfo().key) + m_kmcDKEK->getKeyAndInfo().keyInfo.keyLength);
+}
+
+RawBuffer KeyProvider::getWrappedDomainKEK(const Password &password)
+{
+    if (!m_isInitialized) {
+        ThrowMsg(Exception::InitFailed, "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.label,
+        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;
+        ThrowMsg(Exception::OpensslEngineError, "OPENSSL_ENGINE_ERROR");
+    }
+
+    delete[] concat_user_pass;
+
+    wkmcDKEK.setKeyInfo(&(m_kmcDKEK->getKeyAndInfo().keyInfo));
+
+    int wrappedKeyLength;
+
+    if (0 > (wrappedKeyLength = encryptAes256Gcm(
+        m_kmcDKEK->getKeyAndInfo().key,
+        m_kmcDKEK->getKeyAndInfo().keyInfo.keyLength,
+        PKEK1,
+        m_kmcDKEK->getKeyAndInfo().keyInfo.iv,
+        wkmcDKEK.getWrappedKeyAndInfo().wrappedKey,
+        wkmcDKEK.getWrappedKeyAndInfo().keyInfo.tag))) {
+
+        ThrowMsg(Exception::InitFailed, "WrapDKEK Failed in KeyProvider::getDomainKEK");
+    }
+
+    wkmcDKEK.setKeyInfoKeyLength((unsigned int)wrappedKeyLength);
+
+    LogDebug("getDomainKEK(password) Success");
+    return toRawBuffer(wkmcDKEK.getWrappedKeyAndInfo());
+}
+
+
+RawBuffer KeyProvider::getPureDEK(const RawBuffer &DEKInWrapForm)
+{
+    if (!m_isInitialized) {
+        ThrowMsg(Exception::InitFailed, "Object not initialized!");
+    }
+
+    if (DEKInWrapForm.size() != sizeof(WrappedKeyAndInfo)){
+        LogError("input size:" << DEKInWrapForm.size()
+                  << " Expected: " << sizeof(WrappedKeyAndInfo));
+        ThrowMsg(Exception::InputParamError,
+                "buffer doesn't have proper size to store "
+                "WrappedKeyAndInfo in KeyProvider::getPureDEK");
+    }
+
+    KeyAndInfoContainer kmcDEK = KeyAndInfoContainer();
+    WrappedKeyAndInfoContainer wkmcDEK = WrappedKeyAndInfoContainer(DEKInWrapForm.data());
+
+    uint8_t PKEK2[MAX_KEY_SIZE];
+    int keyLength;
+
+    if (!PKCS5_PBKDF2_HMAC_SHA1(
+        wkmcDEK.getWrappedKeyAndInfo().keyInfo.label,
+        strlen(wkmcDEK.getWrappedKeyAndInfo().keyInfo.label),
+        m_kmcDKEK->getKeyAndInfo().key,
+        MAX_SALT_SIZE,
+        PBKDF2_ITERATIONS,
+        MAX_KEY_SIZE,
+        PKEK2)) {
+
+        ThrowMsg(Exception::OpensslEngineError, "OPENSSL_ENGINE_ERROR");
+    }
+
+    if (0 > (keyLength = decryptAes256Gcm(
+        wkmcDEK.getWrappedKeyAndInfo().wrappedKey,
+        wkmcDEK.getWrappedKeyAndInfo().keyInfo.keyLength,
+        wkmcDEK.getWrappedKeyAndInfo().keyInfo.tag,
+        PKEK2,
+        wkmcDEK.getWrappedKeyAndInfo().keyInfo.iv,
+        kmcDEK.getKeyAndInfo().key))) {
+
+        ThrowMsg(Exception::UnwrapFailed,
+            "UnwrapDEK Failed in KeyProvider::getPureDEK");
+    }
+
+    kmcDEK.setKeyInfoKeyLength((unsigned int)keyLength);
+
+    LogDebug("getPureDEK SUCCESS");
+    return RawBuffer(
+        kmcDEK.getKeyAndInfo().key,
+        (kmcDEK.getKeyAndInfo().key) + kmcDEK.getKeyAndInfo().keyInfo.keyLength);
+}
+
+RawBuffer KeyProvider::generateDEK(const std::string &smackLabel)
+{
+    if (!m_isInitialized) {
+        ThrowMsg(Exception::InitFailed,
+                "Object not initialized!");
+    }
+
+    WrappedKeyAndInfoContainer wkmcDEK = WrappedKeyAndInfoContainer();
+    std::string resized_smackLabel;
+
+    if (smackLabel.length() < APP_LABEL_SIZE)
+        resized_smackLabel = smackLabel;
+    else
+        resized_smackLabel = smackLabel.substr(0, APP_LABEL_SIZE-1);
+
+    uint8_t key[MAX_KEY_SIZE], PKEK2[MAX_KEY_SIZE];
+
+    if (!RAND_bytes(key, m_kmcDKEK->getKeyAndInfo().keyInfo.keyLength) ||
+        !RAND_bytes(wkmcDEK.getWrappedKeyAndInfo().keyInfo.iv, MAX_IV_SIZE)) {
+
+        ThrowMsg(Exception::OpensslEngineError, "OPENSSL_ENGINE_ERROR");
+    }
+
+    if (!PKCS5_PBKDF2_HMAC_SHA1(
+        resized_smackLabel.c_str(),
+        strlen(resized_smackLabel.c_str()),
+        m_kmcDKEK->getKeyAndInfo().key,
+        MAX_SALT_SIZE,
+        PBKDF2_ITERATIONS,
+        MAX_KEY_SIZE,
+        PKEK2)) {
+
+        ThrowMsg(Exception::OpensslEngineError, "OPENSSL_ENGINE_ERROR");
+    }
+
+    int wrappedKeyLength;
+
+    if (0 > (wrappedKeyLength = encryptAes256Gcm(
+        key,
+        m_kmcDKEK->getKeyAndInfo().keyInfo.keyLength,
+        PKEK2,
+        wkmcDEK.getWrappedKeyAndInfo().keyInfo.iv,
+        wkmcDEK.getWrappedKeyAndInfo().wrappedKey,
+        wkmcDEK.getWrappedKeyAndInfo().keyInfo.tag))) {
+
+        ThrowMsg(Exception::GenFailed,
+            "GenerateDEK Failed in KeyProvider::generateDEK");
+    }
+
+    wkmcDEK.setKeyInfoKeyLength((unsigned int)wrappedKeyLength);
+    wkmcDEK.setKeyInfoSalt(m_kmcDKEK->getKeyAndInfo().key, MAX_SALT_SIZE);
+    wkmcDEK.setKeyInfoLabel(resized_smackLabel);
+
+    LogDebug("GenerateDEK Success");
+    return toRawBuffer(wkmcDEK.getWrappedKeyAndInfo());
+}
+
+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));
+        ThrowMsg(Exception::InputParamError,
+                "buffer doesn't have proper size to store "
+                "WrappedKeyAndInfo in KeyProvider::reencrypt");
+    }
+
+    WrappedKeyAndInfoContainer wkmcOldDKEK = WrappedKeyAndInfoContainer(domainKEKInWrapForm.data());
+    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.label,
+        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;
+        ThrowMsg(Exception::OpensslEngineError, "OPENSSL_ENGINE_ERROR");
+    }
+    delete[] concat_user_pass;
+
+    if (0 > (keyLength = decryptAes256Gcm(
+        wkmcOldDKEK.getWrappedKeyAndInfo().wrappedKey,
+        wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo.keyLength,
+        wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo.tag,
+        PKEK1,
+        wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo.iv,
+        kmcDKEK.getKeyAndInfo().key))) {
+
+        ThrowMsg(Exception::PassWordError,
+            "Incorrect Old Password ");
+    }
+
+    kmcDKEK.setKeyInfo(&(wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo));
+    kmcDKEK.setKeyInfoKeyLength((unsigned int)keyLength);
+
+    concat_user_pass = concat_password_user(
+        kmcDKEK.getKeyAndInfo().keyInfo.label,
+        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;
+        ThrowMsg(Exception::OpensslEngineError, "OPENSSL_ENGINE_ERROR");
+    }
+
+    delete[] concat_user_pass;
+
+    int wrappedKeyLength = 0;
+    wkmcNewDKEK.setKeyInfo(&(kmcDKEK.getKeyAndInfo().keyInfo));
+
+    if (0 > (wrappedKeyLength = encryptAes256Gcm(
+        kmcDKEK.getKeyAndInfo().key,
+        kmcDKEK.getKeyAndInfo().keyInfo.keyLength,
+        PKEK1,
+        kmcDKEK.getKeyAndInfo().keyInfo.iv,
+        wkmcNewDKEK.getWrappedKeyAndInfo().wrappedKey,
+        wkmcNewDKEK.getWrappedKeyAndInfo().keyInfo.tag))) {
+
+        ThrowMsg(Exception::UnwrapFailed,
+            "UpdateDomainKEK in KeyProvider::reencrypt Failed");
+    }
+
+    wkmcNewDKEK.setKeyInfoKeyLength((unsigned int)wrappedKeyLength);
+
+    LogDebug("reencrypt SUCCESS");
+    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];
+
+    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))
+        ThrowMsg(Exception::OpensslEngineError, "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;
+        ThrowMsg(Exception::OpensslEngineError, "OPENSSL_ENGINED_ERROR");
+    }
+
+    delete[] concat_user_pass;
+
+    if (0 > (wrappedKeyLength = encryptAes256Gcm(
+        key,
+        MAX_KEY_SIZE,
+        PKEK1,
+        wkmcDKEK.getWrappedKeyAndInfo().keyInfo.iv,
+        wkmcDKEK.getWrappedKeyAndInfo().wrappedKey,
+        wkmcDKEK.getWrappedKeyAndInfo().keyInfo.tag))) {
+
+        ThrowMsg(Exception::GenFailed,
+            "GenerateDomainKEK Failed in KeyProvider::generateDomainKEK");
+    }
+
+    wkmcDKEK.setKeyInfoKeyLength((unsigned int)wrappedKeyLength);
+    wkmcDKEK.setKeyInfoLabel(user);
+
+    LogDebug("generateDomainKEK Success");
+    return toRawBuffer(wkmcDKEK.getWrappedKeyAndInfo());
+}
+
+int KeyProvider::initializeLibrary()
+{
+    LogDebug("initializeLibrary Success");
+    return SUCCESS;
+}
+
+int KeyProvider::closeLibrary()
+{
+    LogDebug("closeLibrary Success");
+    return SUCCESS;
+}
+
+KeyProvider::~KeyProvider()
+{
+    LogDebug("KeyProvider Destructor");
+}
+
+int KeyProvider::encryptAes256Gcm(const unsigned char *plaintext, int plaintext_len, const unsigned char *key, const unsigned char *iv, unsigned char *ciphertext, unsigned char *tag)
+{
+
+    EVP_CIPHER_CTX *ctx;
+    int len;
+    int ciphertext_len = 0;
+
+    if (!(ctx = EVP_CIPHER_CTX_new())) {
+        return OPENSSL_ENGINE_ERROR;
+    }
+
+    if (!EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL)) {
+        return OPENSSL_ENGINE_ERROR;
+    }
+
+    if (!EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv)) {
+        return OPENSSL_ENGINE_ERROR;
+    }
+
+    if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, MAX_IV_SIZE, NULL)) {
+        return OPENSSL_ENGINE_ERROR;
+    }
+
+    if (!EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len)) {
+        return OPENSSL_ENGINE_ERROR;
+    }
+    ciphertext_len = len;
+
+    if (!EVP_EncryptFinal_ex(ctx, ciphertext + len, &len)) {
+        return OPENSSL_ENGINE_ERROR;
+    }
+    ciphertext_len += len;
+
+    if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, MAX_IV_SIZE, tag)) {
+        return OPENSSL_ENGINE_ERROR;
+    }
+
+    EVP_CIPHER_CTX_free(ctx);
+
+    return ciphertext_len;
+}
+
+int KeyProvider::decryptAes256Gcm(const unsigned char *ciphertext, int ciphertext_len, unsigned char *tag, const unsigned char *key, const unsigned char *iv, unsigned char *plaintext)
+{
+
+    EVP_CIPHER_CTX *ctx;
+    int len;
+    int plaintext_len;
+    int ret;
+
+    if (!(ctx = EVP_CIPHER_CTX_new())) {
+        return OPENSSL_ENGINE_ERROR;
+    }
+
+    if (!EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL)) {
+        return OPENSSL_ENGINE_ERROR;
+    }
+    if (!EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv)) {
+        return OPENSSL_ENGINE_ERROR;
+    }
+
+    if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, MAX_IV_SIZE, NULL)) {
+        return OPENSSL_ENGINE_ERROR;
+    }
+
+    if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, MAX_IV_SIZE, tag)) {
+        return OPENSSL_ENGINE_ERROR;
+    }
+
+    if (!EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len)) {
+        return OPENSSL_ENGINE_ERROR;
+    }
+    plaintext_len = len;
+
+    if (!(ret = EVP_DecryptFinal_ex(ctx, plaintext + len, &len))) {
+        return OPENSSL_ENGINE_ERROR;
+    }
+
+    EVP_CIPHER_CTX_free(ctx);
+
+    if (ret > 0) {
+        plaintext_len += len;
+        return plaintext_len;
+    }
+    else {
+        return -1;
+    }
+}
+
+char * KeyProvider::concat_password_user(const char *user, const char *password)
+{
+    char *concat_user_pass = NULL;
+    char *resized_user = NULL;
+    int concat_user_pass_len = 0;
+
+    if (strlen(user) > MAX_LABEL_SIZE-1) {
+        resized_user = new char[MAX_LABEL_SIZE];
+        memcpy(resized_user, user, MAX_LABEL_SIZE-1);
+        resized_user[MAX_LABEL_SIZE-1] = '\0';
+    }
+    else {
+        resized_user = new char[strlen(user)+1];
+        memcpy(resized_user, user, strlen(user));
+        resized_user[strlen(user)] = '\0';
+    }
+    concat_user_pass_len = strlen(resized_user) + strlen(password) + 1;
+    concat_user_pass = new char[concat_user_pass_len];
+
+    memset(concat_user_pass, '\0', concat_user_pass_len);
+    memcpy(concat_user_pass, password, strlen(password));
+    memcpy(&(concat_user_pass[strlen(password)]), user, strlen(user));
+    concat_user_pass[strlen(resized_user) + strlen(password)] = '\0';
+
+    delete[] resized_user;
+    return concat_user_pass;
+}
index 4132043..91e9f15 100644 (file)
 #pragma once
 
-#include <ckm-key-provider.h>
+#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 <ckm/ckm-type.h>
 #include <dpl/exception.h>
 
+#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)
+#define AES_GCM_TAG_SIZE      32
+
+#define PBKDF2_SALT_LEN       16
+#define PBKDF2_ITERATIONS     4096
+
+#define MAX_IV_SIZE           16
+#define MAX_SALT_SIZE         16
+#define MAX_KEY_SIZE          32
+#define MAX_WRAPPED_KEY_SIZE  32
+#define MAX_LABEL_SIZE        32
+#define DOMAIN_NAME_SIZE      32
+#define APP_LABEL_SIZE        32
+
 namespace CKM {
 
-class WrappedKeyMaterialContainer{
+typedef struct KeyComponentsInfo_ {
+    uint32_t keyLength;
+    char label[MAX_LABEL_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;
+
+class WrappedKeyAndInfoContainer{
 public:
-       WrappedKeyMaterialContainer();
-       WrappedKeyMaterialContainer(const unsigned char*);
-       WrappedKeyMaterial& getWrappedKeyMaterial();
-       ~WrappedKeyMaterialContainer();
+    WrappedKeyAndInfoContainer();
+    WrappedKeyAndInfoContainer(const unsigned char*);
+    WrappedKeyAndInfo& getWrappedKeyAndInfo();
+    void setKeyInfoKeyLength(const unsigned int);
+    void setKeyInfoLabel(const std::string);
+    void setKeyInfoSalt(const unsigned char*, const int);
+    void setKeyInfo(const KeyComponentsInfo*);
+    ~WrappedKeyAndInfoContainer();
 private:
-       WrappedKeyMaterial *wrappedKeyMaterial;
+    WrappedKeyAndInfo *wrappedKeyAndInfo;
 };
 
-class KeyMaterialContainer{
+class KeyAndInfoContainer{
 public:
-       class Exception{
-       public:
-               DECLARE_EXCEPTION_TYPE(CKM::Exception, Base)
-       };
-       KeyMaterialContainer();
-       KeyMaterialContainer(const unsigned char*);
-       KeyMaterial& getKeyMaterial();
-       ~KeyMaterialContainer();
+    class Exception{
+    public:
+        DECLARE_EXCEPTION_TYPE(CKM::Exception, Base)
+    };
+    KeyAndInfoContainer();
+    KeyAndInfoContainer(const unsigned char*);
+    KeyAndInfo& getKeyAndInfo();
+    void setKeyInfoKeyLength(const unsigned int);
+    void setKeyInfo(const KeyComponentsInfo*);
+    ~KeyAndInfoContainer();
 private:
-       KeyMaterial *keyMaterial;
+    KeyAndInfo *keyAndInfo;
 };
 
 
 // This is internal api so all functions should throw exception on errors.
 class KeyProvider {
 public:
-       class Exception {
-       public:
-               DECLARE_EXCEPTION_TYPE(CKM::Exception, Base)
-               DECLARE_EXCEPTION_TYPE(Base, InitFailed)
-               DECLARE_EXCEPTION_TYPE(Base, GenFailed)
-               DECLARE_EXCEPTION_TYPE(Base, WrapFailed)
-               DECLARE_EXCEPTION_TYPE(Base, UnwrapFailed)
-               DECLARE_EXCEPTION_TYPE(Base, PassWordError)
-               DECLARE_EXCEPTION_TYPE(Base, InputParamError)
-       };
-
-       // 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(WrappedKeyMaterial))
-       //       throw exception; // buffer does not have proper size to store WrappedKeyMaterial
-       // WrappedKeyMaterial *wkm = static_cast<WrappedKeyMaterial>(keyInWrapForm.data());
-       KeyProvider(const RawBuffer &domainKEKInWrapForm, const Password &password);
-
-       KeyProvider(KeyProvider &&);
-       KeyProvider(const KeyProvider &) = delete;
-       KeyProvider& operator=(const KeyProvider &) = delete;
-       KeyProvider& operator=(KeyProvider &&);
-
-       bool isInitialized();
-
-       // Returns Key used to decrypt database.
-       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);
-
-       // EncryptedKey key extracted from database. Used to encrypt application data.
-       // This key will be used to decrypt/encrypt data in ROW
-       RawBuffer getPureDEK(const RawBuffer &DEKInWrapForm);
-
-       // Returns WRAPPED DEK. This will be written to datbase.
-       // This key will be used to encrypt all application information.
-       // All application are identified by smackLabel.
-       RawBuffer generateDEK(const std::string &smackLabel);
-
-       // 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);
-
-       // 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();
-
-       virtual ~KeyProvider();
+    class Exception {
+    public:
+        DECLARE_EXCEPTION_TYPE(CKM::Exception, Base)
+        DECLARE_EXCEPTION_TYPE(Base, InitFailed)
+        DECLARE_EXCEPTION_TYPE(Base, GenFailed)
+        DECLARE_EXCEPTION_TYPE(Base, WrapFailed)
+        DECLARE_EXCEPTION_TYPE(Base, UnwrapFailed)
+        DECLARE_EXCEPTION_TYPE(Base, PassWordError)
+        DECLARE_EXCEPTION_TYPE(Base, InputParamError)
+        DECLARE_EXCEPTION_TYPE(Base, OpensslEngineError)
+    };
+
+    // 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(KeyProvider &&);
+    KeyProvider(const KeyProvider &) = delete;
+    KeyProvider& operator=(const KeyProvider &) = delete;
+    KeyProvider& operator=(KeyProvider &&);
+
+    bool isInitialized();
+
+    // Returns Key used to decrypt database.
+    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);
+
+    // EncryptedKey key extracted from database. Used to encrypt application data.
+    // This key will be used to decrypt/encrypt data in ROW
+    RawBuffer getPureDEK(const RawBuffer &DEKInWrapForm);
+
+    // Returns WRAPPED DEK. This will be written to datbase.
+    // This key will be used to encrypt all application information.
+    // All application are identified by smackLabel.
+    RawBuffer generateDEK(const std::string &smackLabel);
+
+    // 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);
+
+    // 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();
+
+    virtual ~KeyProvider();
 private:
-       // KeyMaterialContainer class
-       KeyMaterialContainer *m_kmcDKEK;
-       bool m_isInitialized;
-       static bool s_isInitialized;
+    // KeyAndInfoContainer class
+    std::shared_ptr<KeyAndInfoContainer> m_kmcDKEK;
+    bool m_isInitialized;
+
+    static int encryptAes256Gcm(
+        const unsigned char *plaintext,
+        int plaintext_len,
+        const unsigned char *key,
+        const unsigned char *iv,
+        unsigned char *ciphertext,
+        unsigned char *tag);
+
+    static int decryptAes256Gcm(
+        const unsigned char *ciphertext,
+        int ciphertext_len,
+        unsigned char *tag,
+        const unsigned char *key,
+        const unsigned char *iv,
+        unsigned char *plaintext);
+
+    static char * concat_password_user(
+        const char *user,
+        const char *password);
+
 };
 
 } // namespace CKM
-
index 4356512..bbdffab 100644 (file)
@@ -44,7 +44,6 @@ TARGET_LINK_LIBRARIES(${TARGET_TEST_MERGED}
     ${KEY_MANAGER_DEP_LIBRARIES}
     ${TARGET_KEY_MANAGER_CLIENT}
     ${TARGET_KEY_MANAGER_COMMON}
-    ${TARGET_KEY_MANAGER_KEY_PROVIDER}
     boost_unit_test_framework
     )