Change keystore to have the compatiblity with luks 76/106676/14
authorSungbae Yoo <sungbae.yoo@samsung.com>
Thu, 22 Dec 2016 10:49:06 +0000 (19:49 +0900)
committerSungbae Yoo <sungbae.yoo@samsung.com>
Tue, 17 Jan 2017 08:34:12 +0000 (17:34 +0900)
Change-Id: Ie25eb1c1655f3a0feef7d4793a6db3e6d98b30fa
Signed-off-by: Sungbae Yoo <sungbae.yoo@samsung.com>
22 files changed:
lib/ode/external-encryption.cpp
lib/ode/internal-encryption.cpp
server/CMakeLists.txt
server/engine/dmcrypt-engine.cpp
server/engine/dmcrypt-engine.h
server/engine/ecryptfs-engine.cpp
server/engine/ecryptfs-engine.h
server/engine/ext4-engine.cpp [changed mode: 0755->0644]
server/engine/ext4-engine.h [changed mode: 0755->0644]
server/external-encryption.cpp
server/file-footer.cpp [new file with mode: 0644]
server/file-footer.h [new file with mode: 0644]
server/internal-encryption.cpp
server/key-manager/key-generator.cpp [changed mode: 0755->0644]
server/key-manager/key-generator.h [changed mode: 0755->0644]
server/key-manager/key-manager.cpp [changed mode: 0755->0644]
server/key-manager/key-manager.h
server/key-manager/key-store.cpp
server/key-manager/key-store.h
server/key-manager/luks.h [new file with mode: 0644]
server/server.cpp
tests/CMakeLists.txt

index 6647ac4..3ecd74c 100644 (file)
@@ -74,7 +74,7 @@ int ode_external_encryption_change_password(const char* old_password,
        RET_ON_FAILURE(client.connect() == 0, ODE_ERROR_CONNECTION_REFUSED);
        ExternalEncryption external = client.createInterface<ExternalEncryption>();
 
-       return external.changePassword(new_password, old_password);
+       return external.changePassword(old_password, new_password);
 }
 
 int ode_external_encryption_get_state(int* state)
index c626e8d..696e7ae 100644 (file)
@@ -74,7 +74,7 @@ int ode_internal_encryption_change_password(const char* old_password,
        RET_ON_FAILURE(client.connect() == 0, ODE_ERROR_CONNECTION_REFUSED);
        InternalEncryption internal = client.createInterface<InternalEncryption>();
 
-       return internal.changePassword(new_password, old_password);
+       return internal.changePassword(old_password, new_password);
 }
 
 int ode_internal_encryption_get_state(int* state)
index 7287295..49d0d73 100644 (file)
@@ -18,6 +18,7 @@ SET(SERVER_SRCS       main.cpp
                                launchpad.cpp
                                ext4-tool.cpp
                                app-bundle.cpp
+                               file-footer.cpp
                                secure-erase.cpp
                                block-device.cpp
                                internal-encryption.cpp
index 419e6c2..383b5cb 100644 (file)
@@ -24,6 +24,8 @@
 #include <klay/exception.h>
 #include <klay/filesystem.h>
 
+#include "../file-footer.h"
+
 #include "dmcrypt-engine.h"
 
 namespace ode {
@@ -323,4 +325,14 @@ void DMCryptEngine::decrypt(const DMCryptEngine::data &key)
        destroyCryptoBlkDev(DM_LABEL);
 }
 
+const DMCryptEngine::data DMCryptEngine::getKeyMeta()
+{
+       return FileFooter::read(source);
+}
+
+void DMCryptEngine::setKeyMeta(const data &meta)
+{
+       FileFooter::write(source, meta);
+}
+
 } // namespace ode
index 4a9c35b..7dd368d 100644 (file)
@@ -66,6 +66,9 @@ public:
        void encrypt(const data &key);
        void decrypt(const data &key);
 
+       const data getKeyMeta();
+       void setKeyMeta(const data &data);
+
 private:
        std::string source, destination;
        CryptInfo cryptInfo;
index 0031d32..dd48a2e 100644 (file)
@@ -17,6 +17,8 @@
 #include <klay/audit/logger.h>
 #include <klay/exception.h>
 
+#include "../file-footer.h"
+
 #include "ecryptfs-engine.h"
 
 namespace ode {
@@ -1029,4 +1031,14 @@ int EcryptfsEngine::isEcryptfsMountpointMounted(const std::string &path)
        return -1;
 }
 
+const EcryptfsEngine::data EcryptfsEngine::getKeyMeta()
+{
+    return FileFooter::read(mSource);
+}
+
+void EcryptfsEngine::setKeyMeta(const data &meta)
+{
+       FileFooter::write(mSource, meta);
+}
+
 } // namespace ode
index ba6029c..b0d5b44 100644 (file)
@@ -199,9 +199,12 @@ public:
        void encrypt(const data& key);
        void decrypt(const data& key);
 
-       int DoCrypt(const data& key, const char *path, int reqEnc, int excludeMedia);
-       int DoEncrypt(const data& key);
-       int DoDecrypt(const data& key);
+       const data getKeyMeta();
+       void setKeyMeta(const data &data);
+
+       int DoCrypt(const data &key, const char *path, int reqEnc, int excludeMedia);
+       int DoEncrypt(const data &key);
+       int DoDecrypt(const data &key);
        long long CopyImpl(int sfd, int dfd, long long fullsz, bool enctype);
        ssize_t FullRead (int fd, void * buf, size_t count);
        ssize_t FullWrite (int fd, const void * buf, size_t len);
old mode 100755 (executable)
new mode 100644 (file)
index 59769d3..61e3a9f
  *  See the License for the specific language governing permissions and
  *  limitations under the License
  */
-#include <klay/filesystem.h>
-#include <klay/audit/logger.h>
-#include <klay/error.h>
-#include <klay/exception.h>
-
-#include "ext4-engine.h"
-#include "../key-manager/key-generator.h"
 #include <iostream>
 #include <string>
 #include <string.h>
 #include <sys/stat.h>
 #include <sys/sendfile.h>
 
+#include <klay/filesystem.h>
+#include <klay/audit/logger.h>
+#include <klay/error.h>
+#include <klay/exception.h>
+
+#include "../file-footer.h"
+#include "../key-manager/key-generator.h"
+
+#include "ext4-engine.h"
+
 namespace ode {
 
 #define EXT4_MAX_KEY_SIZE 64
@@ -87,9 +90,8 @@ namespace {
 
 const Ext4Engine::data generateKeyDesc(const ode::Ext4Engine::data& key)
 {
-       ode::KeyGenerator KeyGen(EXT4_MAX_KEY_SIZE);
-       Ext4Engine::data keyRef1 = KeyGen.SHA512(key);
-       Ext4Engine::data keyRef2 = KeyGen.SHA512(keyRef1);
+       Ext4Engine::data keyRef1 = ode::KeyGenerator::SHA512(key);
+       Ext4Engine::data keyRef2 = ode::KeyGenerator::SHA512(keyRef1);
        Ext4Engine::data ret(keyRef2.begin(), keyRef2.begin()+EXT4_KEY_DESCRIPTOR_SIZE);
 
        return ret;
@@ -428,4 +430,14 @@ void Ext4Engine::decrypt(const Ext4Engine::data& key)
                ::remove(secondMountPoint.c_str());
 }
 
+const Ext4Engine::data Ext4Engine::getKeyMeta()
+{
+       return FileFooter::read(source);
+}
+
+void Ext4Engine::setKeyMeta(const data &data)
+{
+       FileFooter::write(source, data);
+}
+
 } // namespace ode
old mode 100755 (executable)
new mode 100644 (file)
index 661a248..80922a9
@@ -24,7 +24,7 @@ namespace ode {
 
 class Ext4Engine final {
 public:
-       Ext4Engine(const std::string& src, const std::string& dest);
+       Ext4Engine(const std::string &src, const std::string &dest);
        Ext4Engine(const Ext4Engine&) = delete;
        Ext4Engine(Ext4Engine&&) = delete;
        ~Ext4Engine();
@@ -44,12 +44,15 @@ public:
 
        typedef std::vector<unsigned char> data;
 
-       void mount(const datakey);
+       void mount(const data &key);
        void umount();
 
-       void addKey(const data& key);
-       void encrypt(const data& key);
-       void decrypt(const data& key);
+       void addKey(const data &key);
+       void encrypt(const data &key);
+       void decrypt(const data &key);
+
+       const data getKeyMeta();
+       void setKeyMeta(const data &data);
 
 private:
        std::string source, destination;
index 98986cf..c5eed8c 100644 (file)
@@ -38,7 +38,6 @@ namespace ode {
 
 namespace {
 
-KeyManager keyManager(EXTERNAL_STORAGE_PATH);
 EcryptfsEngine engine(EXTERNAL_STORAGE_PATH, EXTERNAL_STORAGE_PATH);
 
 void killDependedApplications()
@@ -86,9 +85,9 @@ void externalCallback(dbus::Variant parameters)
                INFO("Mounted!!!");
                // TODO
                // Password Popup
-               std::string pw = "tizen";
-               KeyManager::data pwData(pw.begin(), pw.end());
-               engine.mount(keyManager.getDEK(pwData));
+//             std::string pw = "tizen";
+//             KeyManager::data pwData(pw.begin(), pw.end());
+//             engine.mount(keyManager.getDEK(pwData));
        }
 }
 
@@ -117,9 +116,9 @@ void externalCheckMount()
                                INFO("Already Ecryptfs Mounted");
                        }
                        else {
-                               std::string pw = "tizen";
-                               KeyManager::data pwData(pw.begin(), pw.end());
-                               engine.mount(keyManager.getDEK(pwData));
+//                             std::string pw = "tizen";
+//                             KeyManager::data pwData(pw.begin(), pw.end());
+//                             engine.mount(keyManager.getDEK(pwData));
                        }
                }
                else {
@@ -151,18 +150,14 @@ ExternalEncryption::~ExternalEncryption()
 
 int ExternalEncryption::mount(const std::string& password)
 {
-       bool isVerified = false;
        KeyManager::data pwData(password.begin(), password.end());
+       KeyManager keyManager(engine.getKeyMeta());
 
-       try {
-               isVerified = keyManager.verifyPassword(pwData);
-       } catch (runtime::Exception& e) {}
-
-       if (!isVerified) {
-               return -1;
+       if (!keyManager.verifyPassword(pwData)) {
+               return -2;
        }
 
-       engine.mount(keyManager.getDEK(pwData));
+       engine.mount(keyManager.getMasterKey(pwData));
        return 0;
 }
 
@@ -179,28 +174,19 @@ int ExternalEncryption::umount()
 int ExternalEncryption::encrypt(const std::string& password)
 {
        KeyManager::data pwData(password.begin(), password.end());
+       KeyManager keyManager;
 
-       if (keyManager.isInitialized()) {
-               bool isVerified = false;
-               try {
-                       isVerified = keyManager.verifyPassword(pwData);
-               } catch (runtime::Exception& e) {}
-
-               if (!isVerified) {
-                       return -2;
-               }
-       } else {
-               keyManager.initPassword(pwData);
-       }
+       keyManager.initPassword(pwData);
+       engine.setKeyMeta(keyManager.serialize());
 
-       KeyManager::data DEK = keyManager.getDEK(pwData);
-       auto encryptWorker = [DEK, this]() {
+       KeyManager::data MasterKey = keyManager.getMasterKey(pwData);
+       auto encryptWorker = [MasterKey, this]() {
                showProgressUI("Encrypting");
 
                INFO("Close all applications using external storage...");
                killDependedApplications();
                INFO("Encryption started...");
-               engine.encrypt(DEK);
+               engine.encrypt(MasterKey);
                INFO("Sync disk...");
                sync();
                INFO("Encryption completed");
@@ -214,19 +200,15 @@ int ExternalEncryption::encrypt(const std::string& password)
 
 int ExternalEncryption::decrypt(const std::string& password)
 {
-       bool isVerified = false;
        KeyManager::data pwData(password.begin(), password.end());
+       KeyManager keyManager(engine.getKeyMeta());
 
-       try {
-               isVerified = keyManager.verifyPassword(pwData);
-       } catch (runtime::Exception& e) {}
-
-       if (!isVerified) {
-               return -1;
+       if (!keyManager.verifyPassword(pwData)) {
+               return -2;
        }
 
-       KeyManager::data DEK = keyManager.getDEK(pwData);
-       auto decryptWorker = [DEK, this]() {
+       KeyManager::data MasterKey = keyManager.getMasterKey(pwData);
+       auto decryptWorker = [MasterKey, this]() {
                showProgressUI("Decrypting");
 
                INFO("Close all applications using external storage...");
@@ -237,7 +219,7 @@ int ExternalEncryption::decrypt(const std::string& password)
                } catch (runtime::Exception& e) {}
 
                INFO("Decryption started...");
-               engine.decrypt(DEK);
+               engine.decrypt(MasterKey);
                INFO("Sync disk...");
                sync();
                INFO("Decryption completed");
@@ -246,8 +228,6 @@ int ExternalEncryption::decrypt(const std::string& password)
        std::thread asyncWork(decryptWorker);
        asyncWork.detach();
 
-       keyManager.clearPassword();
-
        return 0;
 }
 
@@ -255,18 +235,16 @@ int ExternalEncryption::changePassword(const std::string& oldPassword,
                                                                                const std::string& newPassword)
 {
        KeyManager::data oldPwData(oldPassword.begin(), oldPassword.end());
-       KeyManager::data newPwData(newPassword.begin(), oldPassword.end());
+       KeyManager::data newPwData(newPassword.begin(), newPassword.end());
+       KeyManager keyManager(engine.getKeyMeta());
 
-       bool isVerified = false;
-       try {
-               isVerified = keyManager.verifyPassword(newPwData);
-       } catch (runtime::Exception& e) {}
-
-       if (!isVerified) {
-               return -1;
+       if (!keyManager.verifyPassword(oldPwData)) {
+               return -2;
        }
 
        keyManager.changePassword(oldPwData, newPwData);
+       engine.setKeyMeta(keyManager.serialize());
+
        return 0;
 }
 
diff --git a/server/file-footer.cpp b/server/file-footer.cpp
new file mode 100644 (file)
index 0000000..3fd8e1c
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ *  Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+#include <fcntl.h>
+
+#include <sstream>
+#include <iomanip>
+
+#include <klay/exception.h>
+#include <klay/filesystem.h>
+#include <klay/audit/logger.h>
+
+#include "file-footer.h"
+#include "key-manager/key-generator.h"
+
+namespace ode {
+
+namespace {
+
+const std::string getFileName(const std::string &key)
+{
+       KeyGenerator::data hash = KeyGenerator::MD5(KeyGenerator::data(key.begin(), key.end()));
+       std::stringstream fileName;
+
+       fileName << "/opt/etc/.ode_";
+       fileName << std::hex << std::setfill('0') << std::setw(2);
+       for (unsigned int byte : hash) {
+               fileName << byte;
+       }
+
+       return fileName.str();
+}
+
+} // namsepace
+
+const FileFooter::data FileFooter::read(const std::string &key)
+{
+       std::string fileName(getFileName(key));
+
+       INFO("Footer file : " + fileName);
+
+       runtime::File file(fileName);
+       data value(file.size());
+
+       file.open(O_RDONLY);
+       file.read(value.data(), value.size());
+
+       return value;
+}
+
+void FileFooter::write(const std::string &key, const data &value)
+{
+       std::string fileName(getFileName(key));
+
+       INFO("Footer file : " + fileName);
+
+       runtime::File file(fileName);
+
+       file.create(0600);
+       file.write(value.data(), value.size());
+}
+
+} // namespace ode
diff --git a/server/file-footer.h b/server/file-footer.h
new file mode 100644 (file)
index 0000000..22fa6d0
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ *  Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+
+#ifndef __FILE_FOOTER_H__
+#define __FILE_FOOTER_H__
+
+#include <vector>
+#include <string>
+
+namespace ode {
+
+class FileFooter final {
+public:
+       FileFooter() = delete;
+
+       typedef std::vector<unsigned char> data;
+
+       static const data read(const std::string &key);
+       static void write(const std::string &key, const data &value);
+};
+
+} // namespace ode
+#endif // __FILE_FOOTER_H__
index d6979df..9562530 100644 (file)
@@ -37,7 +37,6 @@ namespace ode {
 
 namespace {
 
-KeyManager keyManager(INTERNAL_STORAGE_PATH);
 DMCryptEngine engine("/dev/mmcblk0p25", INTERNAL_STORAGE_PATH);
 
 void stopDependedSystemdServices()
@@ -99,18 +98,14 @@ InternalEncryption::~InternalEncryption()
 
 int InternalEncryption::mount(const std::string& password)
 {
-       bool isVerified = false;
        KeyManager::data pwData(password.begin(), password.end());
+       KeyManager keyManager(engine.getKeyMeta());
 
-       try {
-               isVerified = keyManager.verifyPassword(pwData);
-       } catch (runtime::Exception& e) {}
-
-       if (!isVerified) {
-               return -1;
+       if (!keyManager.verifyPassword(pwData)) {
+               return -2;
        }
 
-       engine.mount(keyManager.getDEK(pwData));
+       engine.mount(keyManager.getMasterKey(pwData));
        return 0;
 }
 
@@ -127,22 +122,13 @@ int InternalEncryption::umount()
 int InternalEncryption::encrypt(const std::string& password)
 {
        KeyManager::data pwData(password.begin(), password.end());
+       KeyManager keyManager;
 
-       if (keyManager.isInitialized()) {
-               bool isVerified = false;
-               try {
-                       isVerified = keyManager.verifyPassword(pwData);
-               } catch (runtime::Exception& e) {}
-
-               if (!isVerified) {
-                       return -2;
-               }
-       } else {
-               keyManager.initPassword(pwData);
-       }
+       keyManager.initPassword(pwData);
+       engine.setKeyMeta(keyManager.serialize());
 
-       KeyManager::data DEK = keyManager.getDEK(pwData);
-       auto encryptWorker = [DEK, this]() {
+       KeyManager::data MasterKey = keyManager.getMasterKey(pwData);
+       auto encryptWorker = [MasterKey, this]() {
                showProgressUI("Encrypting");
 
                INFO("Close all processes using internal storage...");
@@ -155,7 +141,7 @@ int InternalEncryption::encrypt(const std::string& password)
                }
 
                INFO("Encryption started...");
-               engine.encrypt(DEK);
+               engine.encrypt(MasterKey);
                INFO("Sync disk...");
                sync();
                INFO("Encryption completed");
@@ -170,19 +156,15 @@ int InternalEncryption::encrypt(const std::string& password)
 
 int InternalEncryption::decrypt(const std::string& password)
 {
-       bool isVerified = false;
        KeyManager::data pwData(password.begin(), password.end());
+       KeyManager keyManager(engine.getKeyMeta());
 
-       try {
-               isVerified = keyManager.verifyPassword(pwData);
-       } catch (runtime::Exception& e) {}
-
-       if (!isVerified) {
-               return -1;
+       if (!keyManager.verifyPassword(pwData)) {
+               return -2;
        }
 
-       KeyManager::data DEK = keyManager.getDEK(pwData);
-       auto decryptWorker = [DEK, this]() {
+       KeyManager::data MasterKey = keyManager.getMasterKey(pwData);
+       auto decryptWorker = [MasterKey, this]() {
                showProgressUI("Decrypting");
 
                INFO("Close all processes using internal storage...");
@@ -193,7 +175,7 @@ int InternalEncryption::decrypt(const std::string& password)
                } catch (runtime::Exception& e) {}
 
                INFO("Decryption started...");
-               engine.decrypt(DEK);
+               engine.decrypt(MasterKey);
                INFO("Sync disk...");
                sync();
                INFO("Decryption completed");
@@ -203,8 +185,6 @@ int InternalEncryption::decrypt(const std::string& password)
        std::thread asyncWork(decryptWorker);
        asyncWork.detach();
 
-       keyManager.clearPassword();
-
        return 0;
 }
 
@@ -212,18 +192,16 @@ int InternalEncryption::changePassword(const std::string& oldPassword,
                                                                                const std::string& newPassword)
 {
        KeyManager::data oldPwData(oldPassword.begin(), oldPassword.end());
-       KeyManager::data newPwData(newPassword.begin(), oldPassword.end());
+       KeyManager::data newPwData(newPassword.begin(), newPassword.end());
+       KeyManager keyManager(engine.getKeyMeta());
 
-       bool isVerified = false;
-       try     {
-               isVerified = keyManager.verifyPassword(newPwData);
-       } catch (runtime::Exception& e) {}
-
-       if (!isVerified) {
-               return -1;
+       if (!keyManager.verifyPassword(oldPwData)) {
+               return -2;
        }
 
        keyManager.changePassword(oldPwData, newPwData);
+       engine.setKeyMeta(keyManager.serialize());
+
        return 0;
 }
 
old mode 100755 (executable)
new mode 100644 (file)
index b772db4..44a1a0e
 #include "key-generator.h"
 
 #define PBKDF_DEFAULT_ITERATION 1000
-#define AES_256_CBC_IV "01234567890123456"
-#define AES_256_KEY_LEN 32
-#define AES_BLOCK_LEN 16
+
+#ifdef OPENSSL_NO_AES
+#error This requires AES
+#endif
+
+#ifdef OPENSSL_NO_SHA256
+#error This requires SHA256
+#endif
+
+#ifdef OPENSSL_NO_SHA512
+#error This requires SHA512
+#endif
+
+#ifdef OPENSSL_NO_MD5
+#error This requires MD5
+#endif
 
 namespace ode {
 
-KeyGenerator::KeyGenerator(int size) :
-       keySize(size)
+void KeyGenerator::init()
 {
-       ::OpenSSL_add_all_algorithms();
+       EVP_add_cipher(EVP_aes_256_cbc());
+       EVP_add_digest(EVP_md5());
+       EVP_add_digest(EVP_sha256());
+       EVP_add_digest(EVP_sha512());
 }
 
-KeyGenerator::~KeyGenerator()
+void KeyGenerator::cleanup()
 {
+       EVP_cleanup();
 }
 
-const KeyGenerator::data KeyGenerator::PBKDF(const KeyGenerator::data& pass, const KeyGenerator::data& salt)
+
+const KeyGenerator::data KeyGenerator::PBKDF(const data& pass, const data& salt, size_t iteration, size_t resultSize)
 {
-       data ret(keySize, 0);
-       std::string strPass(pass.begin(), pass.end());
-       std::string strSalt(salt.begin(), salt.end());
+       data ret(resultSize, 0);
 
-       ::PKCS5_PBKDF2_HMAC((char*)strPass.c_str(), strPass.size(),
-                                               (unsigned char*)strSalt.c_str(), strSalt.size(), PBKDF_DEFAULT_ITERATION,
-                                               EVP_sha256(), keySize, reinterpret_cast<unsigned char*>(ret.data()));
+       ::PKCS5_PBKDF2_HMAC((char *)pass.data(), pass.size(),
+                                               salt.data(), salt.size(), iteration,
+                                               EVP_sha256(), resultSize, ret.data());
 
        return ret;
 }
 
-const KeyGenerator::data KeyGenerator::AESEncrypt(const KeyGenerator::data& key, const KeyGenerator::data& in)
+const KeyGenerator::data KeyGenerator::AESEncrypt(const data& in, const data& key, const data& iv)
 {
-       data ret(keySize, 0);
-       std::string strKey(key.begin(), key.end());
-       std::string strIn(in.begin(), in.end());
+       data ret(in.size(), 0);
        EVP_CIPHER_CTX* ctx;
        int outLen, len;
 
-       //if ((strKey.size() != AES_256_KEY_LEN) || (strIn.size() % AES_BLOCK_LEN != 0))
-
        ctx = ::EVP_CIPHER_CTX_new();
 
-       ::EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, (unsigned char*)strKey.c_str(), (unsigned char*)AES_256_CBC_IV);
+       ::EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key.data(), iv.data());
 
        ::EVP_CIPHER_CTX_set_padding(ctx, 0);
-       ::EVP_EncryptUpdate(ctx, reinterpret_cast<unsigned char*>(ret.data()), &len, (unsigned char*)strIn.c_str(), strIn.size());
+       ::EVP_EncryptUpdate(ctx, ret.data(), &len, in.data(), in.size());
        outLen = len;
 
        ::EVP_EncryptFinal_ex(ctx, &ret[len], &len);
@@ -82,22 +93,18 @@ const KeyGenerator::data KeyGenerator::AESEncrypt(const KeyGenerator::data& key,
        return ret;
 }
 
-const KeyGenerator::data KeyGenerator::AESDecrypt(const KeyGenerator::data& key, const KeyGenerator::data& in)
+const KeyGenerator::data KeyGenerator::AESDecrypt(const data& in, const data& key, const data& iv)
 {
-       data ret(keySize, 0);
-       std::string strKey(key.begin(), key.end());
-       std::string strIn(in.begin(), in.end());
+       data ret(in.size(), 0);
        EVP_CIPHER_CTX* ctx;
 
        int len, len1;
 
-       //if ((strKey.size() != AES_256_KEY_LEN) || (strIn.size() % AES_BLOCK_LEN != 0))
-
        ctx = ::EVP_CIPHER_CTX_new();
 
-       ::EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, (unsigned char*)strKey.c_str(), (unsigned char*)AES_256_CBC_IV);
+       ::EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key.data(), iv.data());
        ::EVP_CIPHER_CTX_set_padding(ctx, 0);
-       ::EVP_DecryptUpdate(ctx, reinterpret_cast<unsigned char*>(ret.data()), &len, (unsigned char*)strIn.c_str(), keySize);
+       ::EVP_DecryptUpdate(ctx, ret.data(), &len, in.data(), in.size());
 
        len1 = len;
 
@@ -109,45 +116,49 @@ const KeyGenerator::data KeyGenerator::AESDecrypt(const KeyGenerator::data& key,
        return ret;
 }
 
-const KeyGenerator::data KeyGenerator::HMAC(const KeyGenerator::data& original, const KeyGenerator::data& key)
+const KeyGenerator::data KeyGenerator::HMAC(const data& key, const data& in)
 {
-       data ret(keySize, 0);
-
+       data ret(256 / 8);
        unsigned int md_len;
-       std::string strOrigin(key.begin(), key.end());
-       std::string strKey(original.begin(), original.end());
-       std::string result;
 
-       ::HMAC(EVP_sha256(), (unsigned char*)strKey.c_str(), strKey.size(),
-                                               (unsigned char*)strOrigin.c_str(), strOrigin.size(),
-                                               reinterpret_cast<unsigned char*>(ret.data()), &md_len);
+       ::HMAC(EVP_sha256(), key.data(), key.size(), in.data(), in.size(),
+                                               ret.data(), &md_len);
 
        return ret;
 }
 
-const KeyGenerator::data KeyGenerator::RNG()
+const KeyGenerator::data KeyGenerator::RNG(size_t resultSize)
 {
-       data ret(keySize);
+       data ret(resultSize);
 
-       ::RAND_bytes(reinterpret_cast<unsigned char*>(ret.data()), keySize);
+       ::RAND_bytes(ret.data(), resultSize);
 
        return ret;
 }
 
-const KeyGenerator::data KeyGenerator::MD5(const KeyGenerator::data& in)
+const KeyGenerator::data KeyGenerator::MD5(const data& in)
 {
-       data ret(MD5_DIGEST_LENGTH);
+       data ret(128 / 8);
 
-       ::MD5((unsigned char*)in.data(), in.size(), (unsigned char*)ret.data());
+       ::MD5(in.data(), in.size(), ret.data());
 
        return ret;
 }
 
-const KeyGenerator::data KeyGenerator::SHA512(const KeyGenerator::data& in)
+const KeyGenerator::data KeyGenerator::SHA256(const data& in)
+{
+    data ret(256 / 8);
+
+    ::SHA256(in.data(), in.size(), ret.data());
+
+    return ret;
+}
+
+const KeyGenerator::data KeyGenerator::SHA512(const data& in)
 {
-    data ret(SHA512_DIGEST_LENGTH);
+    data ret(512 / 8);
 
-    ::SHA512((unsigned char*)in.data(), in.size(), (unsigned char*)ret.data());
+    ::SHA512(in.data(), in.size(), ret.data());
 
     return ret;
 }
old mode 100755 (executable)
new mode 100644 (file)
index 1653d58..00a8dda
@@ -23,26 +23,26 @@ namespace ode {
 
 class KeyGenerator final {
 public:
-       KeyGenerator(int size);
+       KeyGenerator() = delete;
        KeyGenerator(const KeyGenerator&) = delete;
        KeyGenerator(KeyGenerator&&) = delete;
-       ~KeyGenerator();
 
        KeyGenerator& operator=(const KeyGenerator&) = delete;
        KeyGenerator& operator=(KeyGenerator&&) = delete;
 
        typedef std::vector<unsigned char> data;
 
-       const data PBKDF(const data& pass, const data& salt);
-       const data AESEncrypt(const data& key, const data& in);
-       const data AESDecrypt(const data& key, const data& in);
-       const data HMAC(const data& original, const data& key);
-       const data RNG();
-       const data MD5(const data& in);
-       const data SHA512(const data& in);
-
-private:
-       int keySize;
+       static void init();
+       static void cleanup();
+
+       static const data PBKDF(const data& pass, const data& salt, size_t iteration, size_t resultSize);
+       static const data AESEncrypt(const data& in, const data& key, const data& iv);
+       static const data AESDecrypt(const data& in, const data& key, const data& iv);
+       static const data HMAC(const data& in, const data& key);
+       static const data RNG(size_t resultSize);
+       static const data MD5(const data& in);
+       static const data SHA256(const data& in);
+       static const data SHA512(const data& in);
 };
 
 } // namespace ode
old mode 100755 (executable)
new mode 100644 (file)
index a584197..2bff609
  *  See the License for the specific language governing permissions and
  *  limitations under the License
  */
+#include <klay/exception.h>
+
 #include "key-manager.h"
+#include "key-generator.h"
+
+#define MASTER_KEY_LENGTH (256 / 8)
+#define ITERATION_COUNT 1000
 
 namespace ode {
 
-KeyManager::KeyManager(const std::string& storeName) :
-       store(storeName), keyGen(store.getKeySize())
+KeyManager::KeyManager()
+{
+}
+
+KeyManager::KeyManager(const data& data) :
+       store(data)
 {
 }
 
@@ -26,86 +36,98 @@ KeyManager::~KeyManager()
 {
 }
 
-bool KeyManager::isInitialized()
+const KeyManager::data KeyManager::serialize() const
 {
-       return store.isInitialized();
+       return store.serialize();
 }
 
-void KeyManager::initPassword(const KeyManager::data& password)
+const KeyManager::data KeyManager::newMasterKey()
 {
-       data salt, edk, emk;
-       data mk, dek;
+       data masterKey = KeyGenerator::RNG(MASTER_KEY_LENGTH);
+       data masterKeyDigestSalt = KeyGenerator::RNG(store.getMasterKeyDigestSaltLength());
 
-       salt = keyGen.RNG();
-       mk = keyGen.PBKDF(password, salt);
-       dek = keyGen.RNG();
+       store.setMasterKeyLength(masterKey.size());
 
-       edk = keyGen.AESEncrypt(mk, dek);
-       emk = keyGen.HMAC(mk, edk);
+       store.setMasterKeyDigestSalt(masterKeyDigestSalt);
+       store.setMasterKeyDigestIteration(ITERATION_COUNT);
+       store.setMasterKeyDigest(KeyGenerator::PBKDF(masterKey,
+               masterKeyDigestSalt,
+               store.getMasterKeyDigestIteration(),
+               store.getMasterKeyDigestLength()));
 
-       store.setSalt(salt);
-       store.setEDK(edk);
-       store.setEMK(emk);
-       store.flush();
+       return masterKey;
 }
 
-void KeyManager::changePassword(const KeyManager::data& old_password,
-                                                               const KeyManager::data& new_password)
+const KeyManager::data KeyManager::getMasterKey(const data& password) const
 {
-       data salt, edk, emk;
-       data mk, dek;
+       data derivedPassword = KeyGenerator::PBKDF(password,
+               store.getPasswordSalt(),
+               store.getPasswordIteration(),
+               store.getMasterKeyLength());
+
+       data masterKeyCandidate = KeyGenerator::AESDecrypt(
+               store.getEncryptedMasterKey(),
+               derivedPassword,
+               KeyGenerator::SHA256(derivedPassword));
+
+       data masterKeyCandidateDigest = KeyGenerator::PBKDF(masterKeyCandidate,
+               store.getMasterKeyDigestSalt(),
+               store.getMasterKeyDigestIteration(),
+               store.getMasterKeyDigestLength());
+
+       if (masterKeyCandidateDigest == store.getMasterKeyDigest()) {
+               return masterKeyCandidate;
+       }
 
-       salt = store.getSalt();
-       edk = store.getEDK();
+       throw runtime::Exception("Password doesn't match!");
+}
 
-       mk = keyGen.PBKDF(old_password, salt);
-       dek = keyGen.AESDecrypt(mk, edk);
+void KeyManager::setPassword(const data& masterKey, const data& password) {
+       data passwordSalt = KeyGenerator::RNG(store.getPasswordSaltLength());
 
-       salt = keyGen.RNG();
-       mk = keyGen.PBKDF(new_password, salt);
-       edk = keyGen.AESEncrypt(mk, dek);
-       emk = keyGen.HMAC(mk, edk);
+       store.setPasswordSalt(passwordSalt);
+       store.setPasswordIteration(ITERATION_COUNT);
 
-       store.setSalt(salt);
-       store.setEDK(edk);
-       store.setEMK(emk);
-       store.flush();
-}
+       data derivedPassword = KeyGenerator::PBKDF(password,
+               store.getPasswordSalt(),
+               store.getPasswordIteration(),
+               store.getMasterKeyLength());
 
-bool KeyManager::verifyPassword(const KeyManager::data& password)
-{
-       data salt, edk, emk;
-       data mk;
+       store.setEncryptedMasterKey(KeyGenerator::AESEncrypt(
+               masterKey,
+               derivedPassword,
+               KeyGenerator::SHA256(derivedPassword)));
+}
 
-       salt = store.getSalt();
-       edk = store.getEDK();
-       emk = store.getEMK();
 
-       mk = keyGen.PBKDF(password, salt);
+void KeyManager::initPassword(const data& password)
+{
+       store.setCipherName("aes");
+       store.setCipherMode("cbc-essiv:sha256");
+       store.setHashSpec("sha256");
 
-       if (emk == keyGen.HMAC(mk, edk)) {
-               return true;
-       } else {
-               return false;
-       }
+       data masterKey = newMasterKey();
+       setPassword(newMasterKey(), password);
 }
 
-void KeyManager::clearPassword()
+void KeyManager::changePassword(const data& old_password,
+                                                               const data& new_password)
 {
-       store.remove();
+       try {
+               setPassword(getMasterKey(old_password), new_password);
+       } catch (runtime::Exception &e) {
+               throw runtime::Exception("Password doesn't match!");
+       }
 }
 
-KeyManager::data KeyManager::getDEK(const KeyManager::data& password)
+bool KeyManager::verifyPassword(const data& password) const
 {
-       data salt, edk;
-       data mk;
-
-       salt = store.getSalt();
-       edk = store.getEDK();
-
-       mk = keyGen.PBKDF(password, salt);
-
-       return keyGen.AESDecrypt(mk, edk);
+       try {
+               getMasterKey(password);
+       } catch (runtime::Exception &e) {
+               return false;
+       }
+       return true;
 }
 
 } // namespace ode
index 17db47f..b8138ba 100644 (file)
 #define __KEY_MANAGER_H__
 
 #include "key-store.h"
-#include "key-generator.h"
 
 namespace ode {
 
 class KeyManager final {
 public:
-       KeyManager(const std::string& storeName);
+       typedef std::vector<unsigned char> data;
+
+       KeyManager();
+       KeyManager(const data&);
        KeyManager(const KeyManager&) = delete;
        KeyManager(KeyManager&&) = delete;
        ~KeyManager();
@@ -32,20 +34,18 @@ public:
        KeyManager& operator=(const KeyManager&) = delete;
        KeyManager& operator=(KeyManager&&) = delete;
 
-       typedef std::vector<unsigned char> data;
+       const data serialize() const;
 
-       bool isInitialized();
+       const data newMasterKey();
+       const data getMasterKey(const data& password) const;
+       void setPassword(const data& masterKey, const data& password);
 
        void initPassword(const data& password);
        void changePassword(const data& old_password, const data& new_password);
-       bool verifyPassword(const data& password);
-       void clearPassword();
-
-       data getDEK(const data& password);
+       bool verifyPassword(const data& password) const;
 
 private:
        KeyStore store;
-       KeyGenerator keyGen;
 };
 
 } // namespace ode
index 896de3f..e1aec0d 100644 (file)
@@ -14,6 +14,7 @@
  *  limitations under the License
  */
 #include <fcntl.h>
+#include <arpa/inet.h>
 #include <openssl/md5.h>
 
 #include <algorithm>
 #include <klay/audit/logger.h>
 #include <klay/exception.h>
 
-#include "key-generator.h"
 #include "key-store.h"
-
-#define FOOTER_FILE_PATH "/opt/etc/.ode_footer"
-
-#define KEY_SIZE            (256 / 8)
-#define KEY_ENTRY_SIZE   (KEY_SIZE * 4)
-
-#define KEY_HNAME_OFFSET (KEY_SIZE * 0)
-#define KEY_EDK_OFFSET   (KEY_SIZE * 1)
-#define KEY_EMK_OFFSET   (KEY_SIZE * 2)
-#define KEY_SALT_OFFSET  (KEY_SIZE * 3)
+#include "key-generator.h"
 
 namespace ode {
 
-/*
- * Design: store fixed size 4 elements (NAME, EDK, EMK, Salt)
- *      <------------------ 32 byte --------------------->
- *  00h |----------- Hashed KeyStore Name ---------------|
- *  40h |--------------------- EDK ----------------------|
- * 100h |--------------------- EMK ----------------------|
- * 140h |--------------------- SALT ---------------------|
- */
+KeyStore::KeyStore()
+{
+}
 
-KeyStore::KeyStore(const std::string &name) :
-       edk(KEY_SIZE), emk(KEY_SIZE), salt(KEY_SIZE)
+KeyStore::KeyStore(const data &raw)
 {
-       runtime::File file(FOOTER_FILE_PATH);
+       if (raw.size() <= sizeof(luks)) {
+               throw runtime::Exception("the size of raw data is not enough");
+       }
 
-       hname = KeyGenerator(KEY_SIZE).MD5(data(name.begin(), name.end()));
+       ::memcpy(&luks, raw.data(), sizeof(luks));
+       keyMaterial = data(raw.begin() + sizeof(luks), raw.end());
+}
 
-       if (!file.exists()) {
-               offset = -1;
-               file.create(0600);
-               file.close();
-               return;
-       }
+KeyStore::~KeyStore()
+{
+}
 
-       file.open(O_RDONLY);
+const KeyStore::data KeyStore::serialize() const
+{
+       data result((unsigned char *)&luks,
+                               ((unsigned char *)&luks) + sizeof(LUKSHeader));
+       result.insert(result.end(), keyMaterial.begin(), keyMaterial.end());
 
-       //find matched block offset
-       int fileSize = file.size();
-       for (offset = 0; offset < fileSize; offset += KEY_ENTRY_SIZE) {
-               file.lseek(offset, SEEK_SET);
+       return result;
+}
 
-               data current(KEY_SIZE);
-               file.read(current.data(), KEY_SIZE);
+const std::string KeyStore::getCipherName() const
+{
+       return std::string(luks.cipherName);
+}
 
-               if (std::equal(hname.begin(), hname.end(), current.begin())) {
-                       file.read(edk.data(), KEY_SIZE);
-                       file.read(emk.data(), KEY_SIZE);
-                       file.read(salt.data(), KEY_SIZE);
-                       file.close();
-                       return;
-               }
-       }
+const std::string KeyStore::getCipherMode() const
+{
+       return std::string(luks.cipherMode);
+}
+
+const std::string KeyStore::getHashSpec() const
+{
+       return std::string(luks.hashSpec);
+}
 
-       offset = -1;
-       file.close();
+void KeyStore::setCipherName(const std::string &name)
+{
+       char *buf = (char *)luks.cipherName;
+       ::strncpy(buf, name.c_str(), sizeof(luks.cipherName) - 2);
+       buf[sizeof(luks.cipherName) - 1] = '\0';
 }
 
-KeyStore::~KeyStore()
+void KeyStore::setCipherMode(const std::string &mode)
 {
+       char *buf = (char *)luks.cipherMode;
+       ::strncpy(buf, mode.c_str(), sizeof(luks.cipherMode) - 2);
+       buf[sizeof(luks.cipherMode) - 1] = '\0';
 }
 
-size_t KeyStore::getKeySize() const
+void KeyStore::setHashSpec(const std::string &spec)
 {
-       return KEY_SIZE;
+       char *buf = (char *)luks.hashSpec;
+       ::strncpy(buf, spec.c_str(), sizeof(luks.hashSpec) - 2);
+       buf[sizeof(luks.hashSpec) - 1] = '\0';
 }
 
-bool KeyStore::isInitialized() const
+unsigned int KeyStore::getMasterKeyLength() const
 {
-       return offset >= 0;
+       return ::ntohl(luks.keyBytes);
 }
 
-KeyStore::data KeyStore::getEDK() const
+void KeyStore::setMasterKeyLength(unsigned int length)
 {
-       if (offset < 0) {
-               throw runtime::Exception("Store is empty");
-       }
-       return edk;
+       luks.keyBytes = ::htonl(length);
 }
 
-KeyStore::data KeyStore::getEMK() const
+void KeyStore::setEncryptedMasterKey(const data key)
 {
-       if (offset < 0) {
-               throw runtime::Exception("Store is empty");
+       keyMaterial = key;
+       luks.keyslot[0].active = ::htonl(0x00AC71F3);
+       luks.keyslot[0].stripes = ::htonl(keyMaterial.size() / getMasterKeyLength());
+       luks.keyslot[0].keyMaterialOffset = ::htonl(sizeof(LUKSHeader));
+
+       luks.payloadOffset = sizeof(LUKSHeader) + keyMaterial.size();
+       if (luks.payloadOffset % 512 != 0) {
+               luks.payloadOffset += 512 - luks.payloadOffset % 512;
        }
-       return emk;
+       luks.payloadOffset = ::htonl(luks.payloadOffset);
 }
 
-KeyStore::data KeyStore::getSalt() const
+const KeyStore::data& KeyStore::getEncryptedMasterKey() const
 {
-       if (offset < 0) {
-               throw runtime::Exception("Store is empty");
-       }
-       return salt;
+       return keyMaterial;
 }
 
-void KeyStore::setEDK(const KeyStore::data &key)
+const KeyStore::data KeyStore::getPasswordSalt() const
 {
-       edk = key;
+       unsigned char *buf = (unsigned char *)luks.keyslot[0].passwordSalt;
+       return data(buf, buf + sizeof(luks.keyslot[0].passwordSalt));
 }
 
-void KeyStore::setEMK(const KeyStore::data &key)
+unsigned int KeyStore::getPasswordIteration() const
 {
-       emk = key;
+       return ::ntohl(luks.keyslot[0].passwordIteration);
 }
 
-void KeyStore::setSalt(const KeyStore::data &key)
+unsigned int KeyStore::getPasswordSaltLength() const
 {
-       salt = key;
+       return sizeof(luks.keyslot[0].passwordSalt);
 }
 
-void KeyStore::flush()
+void KeyStore::setPasswordSalt(const data salt)
 {
-       runtime::File file(FOOTER_FILE_PATH);
+       ::memcpy(luks.keyslot[0].passwordSalt, salt.data(),
+                               sizeof(luks.keyslot[0].passwordSalt));
+}
 
-       file.open(O_RDWR);
+void KeyStore::setPasswordIteration(unsigned int count)
+{
+       luks.keyslot[0].passwordIteration = ::htonl(count);
+}
 
-       if (offset < 0) {
-               //find empty block offset
-               int fileSize = file.size();
-               data empty = KeyGenerator(KEY_SIZE).MD5(data(0));
+const KeyStore::data KeyStore::getMasterKeyDigest() const
+{
+       unsigned char *buf = (unsigned char *)luks.mkDigest;
+       return data(buf, buf + sizeof(luks.mkDigest));
+}
 
-               for (offset = 0; offset < fileSize; offset += KEY_ENTRY_SIZE) {
-                       file.lseek(offset, SEEK_SET);
+const KeyStore::data KeyStore::getMasterKeyDigestSalt() const
+{
+       unsigned char *buf = (unsigned char *)luks.mkDigestSalt;
+       return data(buf, buf + sizeof(luks.mkDigestSalt));
+}
 
-                       data current(KEY_SIZE);
-                       file.read(current.data(), KEY_SIZE);
+unsigned int KeyStore::getMasterKeyDigestIteration() const
+{
+       return ::ntohl(luks.mkDigestIteration);
+}
 
-                       if (std::equal(empty.begin(), empty.end(), current.begin())) {
-                               break;
-                       }
-               }
-       }
+unsigned int KeyStore::getMasterKeyDigestLength() const
+{
+       return sizeof(luks.mkDigest);
+}
 
-       file.lseek(offset, SEEK_SET);
-       file.write(hname.data(), KEY_SIZE);
-       file.write(edk.data(), KEY_SIZE);
-       file.write(emk.data(), KEY_SIZE);
-       file.write(salt.data(), KEY_SIZE);
-       file.close();
+unsigned int KeyStore::getMasterKeyDigestSaltLength() const
+{
+       return sizeof(luks.mkDigestSalt);
 }
 
-void KeyStore::remove()
+void KeyStore::setMasterKeyDigest(const data digest)
 {
-       data empty = KeyGenerator(KEY_SIZE).MD5(data(0));
+       ::memcpy(luks.mkDigest, digest.data(), sizeof(luks.mkDigest));
+}
 
-       runtime::File file(FOOTER_FILE_PATH);
-       file.open(O_WRONLY);
-       file.lseek(offset, SEEK_SET);
-       file.write(empty.data(), KEY_SIZE);
-       file.close();
+void KeyStore::setMasterKeyDigestSalt(const data salt)
+{
+       ::memcpy(luks.mkDigestSalt, salt.data(), sizeof(luks.mkDigestSalt));
+}
 
-       offset = -1;
+void KeyStore::setMasterKeyDigestIteration(unsigned int count)
+{
+       luks.mkDigestIteration = ::htonl(count);
 }
 
 } // namespace ode
index ac67e85..e50c129 100644 (file)
 
 #include <klay/filesystem.h>
 
+#include "luks.h"
+
 namespace ode {
 
 class KeyStore final {
 public:
-       KeyStore(const std::string &name);
+       typedef std::vector<unsigned char> data;
+
+       KeyStore();
+       KeyStore(const data &raw);
        KeyStore(const KeyStore &) = delete;
        KeyStore(KeyStore &&) = delete;
        ~KeyStore();
@@ -34,26 +39,39 @@ public:
        KeyStore &operator=(const KeyStore &) = delete;
        KeyStore &operator=(KeyStore &&) = delete;
 
-       size_t getKeySize() const;
+       const data serialize() const;
 
-       bool isInitialized() const;
+       const std::string getCipherName() const;
+       const std::string getCipherMode() const;
+       const std::string getHashSpec() const;
+       void setCipherName(const std::string &name);
+       void setCipherMode(const std::string &mode);
+       void setHashSpec(const std::string &hash);
 
-       typedef std::vector<unsigned char> data;
+       unsigned int getMasterKeyLength() const;
+       void setMasterKeyLength(unsigned int length);
 
-       data getEDK() const;
-       data getEMK() const;
-       data getSalt() const;
+       const data& getEncryptedMasterKey() const;
+       void setEncryptedMasterKey(const data salt);
 
-       void setEDK(const data &key);
-       void setEMK(const data &key);
-       void setSalt(const data &key);
+       const data getPasswordSalt() const;
+       unsigned int getPasswordIteration() const;
+       unsigned int getPasswordSaltLength() const;
+       void setPasswordSalt(const data salt);
+       void setPasswordIteration(unsigned int count);
 
-       void flush();
-       void remove();
+       const data getMasterKeyDigest() const;
+       const data getMasterKeyDigestSalt() const;
+       unsigned int getMasterKeyDigestLength() const;
+       unsigned int getMasterKeyDigestSaltLength() const;
+       unsigned int getMasterKeyDigestIteration() const;
+       void setMasterKeyDigest(const data digest);
+       void setMasterKeyDigestSalt(const data salt);
+       void setMasterKeyDigestIteration(unsigned int count);
 
 private:
-       data hname, edk, emk, salt;
-       int offset;
+       LUKSHeader luks;
+       data keyMaterial;
 };
 
 } // namespace ode
diff --git a/server/key-manager/luks.h b/server/key-manager/luks.h
new file mode 100644 (file)
index 0000000..c3fdf25
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ *  Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+
+#ifndef __LUKS_H__
+#define __LUKS_H__
+
+#include <cstdint>
+
+struct LUKSHeader final {
+       char magic[6];
+       uint16_t version;
+       char cipherName[32];
+       char cipherMode[32];
+       char hashSpec[32];
+       uint32_t payloadOffset;
+       uint32_t keyBytes;
+       char mkDigest[20];
+       char mkDigestSalt[32];
+       uint32_t mkDigestIteration;
+       char uuid[40];
+
+       struct {
+               uint32_t active;
+               uint32_t passwordIteration;
+               char passwordSalt[32];
+               uint32_t keyMaterialOffset;
+               uint32_t stripes;
+       } keyslot[1];
+
+       char padding[256];
+
+       LUKSHeader() :
+               magic{'L', 'U', 'K', 'S', 0xba, 0xbe}, version(1)
+       {
+               for (auto &key : keyslot) {
+                       unsigned char *buf = (unsigned char*)&key.active;
+                       buf[0] = 0x0;
+                       buf[1] = 0x0;
+                       buf[2] = 0xDE;
+                       buf[3] = 0xAD;
+               }
+       }
+};
+
+#endif // __LUKS_H__
index 4a9cefe..e948ebb 100644 (file)
@@ -19,6 +19,7 @@
 #include "rmi/secure-erase.h"
 #include "rmi/internal-encryption.h"
 #include "rmi/external-encryption.h"
+#include "key-manager/key-generator.h"
 
 #include "server.h"
 
@@ -43,10 +44,13 @@ Server::Server()
        secureErase.reset(new ode::SecureErase(*this));
        internalEncryption.reset(new ode::InternalEncryption(*this));
        externalEncryption.reset(new ode::ExternalEncryption(*this));
+
+       ode::KeyGenerator::init();
 }
 
 Server::~Server()
 {
+       ode::KeyGenerator::cleanup();
 }
 
 void Server::run()
index 232d192..4fc8129 100755 (executable)
@@ -19,6 +19,7 @@ SET(TEST_SRC  main.cpp
                                ext4-engine.cpp
                                dmcrypt-engine.cpp
                                ecryptfs-engine.cpp
+                               ../server/file-footer.cpp
                                ../server/engine/ext4-engine.cpp
                                ../server/engine/ecryptfs-engine.cpp
                                ../server/key-manager/key-generator.cpp