From c44b56ba1a8fdf2b24759a19192cc4ab5c5ce3c1 Mon Sep 17 00:00:00 2001 From: Sungbae Yoo Date: Thu, 22 Dec 2016 19:49:06 +0900 Subject: [PATCH] Change keystore to have the compatiblity with luks Change-Id: Ie25eb1c1655f3a0feef7d4793a6db3e6d98b30fa Signed-off-by: Sungbae Yoo --- lib/ode/external-encryption.cpp | 2 +- lib/ode/internal-encryption.cpp | 2 +- server/CMakeLists.txt | 1 + server/engine/dmcrypt-engine.cpp | 12 ++ server/engine/dmcrypt-engine.h | 3 + server/engine/ecryptfs-engine.cpp | 12 ++ server/engine/ecryptfs-engine.h | 9 +- server/engine/ext4-engine.cpp | 32 ++-- server/engine/ext4-engine.h | 13 +- server/external-encryption.cpp | 78 ++++------ server/file-footer.cpp | 75 ++++++++++ server/file-footer.h | 36 +++++ server/internal-encryption.cpp | 66 +++------ server/key-manager/key-generator.cpp | 107 ++++++++------ server/key-manager/key-generator.h | 24 +-- server/key-manager/key-manager.cpp | 138 ++++++++++-------- server/key-manager/key-manager.h | 18 +-- server/key-manager/key-store.cpp | 211 ++++++++++++++------------- server/key-manager/key-store.h | 46 ++++-- server/key-manager/luks.h | 58 ++++++++ server/server.cpp | 4 + tests/CMakeLists.txt | 1 + 22 files changed, 592 insertions(+), 356 deletions(-) mode change 100755 => 100644 server/engine/ext4-engine.cpp mode change 100755 => 100644 server/engine/ext4-engine.h create mode 100644 server/file-footer.cpp create mode 100644 server/file-footer.h mode change 100755 => 100644 server/key-manager/key-generator.cpp mode change 100755 => 100644 server/key-manager/key-generator.h mode change 100755 => 100644 server/key-manager/key-manager.cpp create mode 100644 server/key-manager/luks.h diff --git a/lib/ode/external-encryption.cpp b/lib/ode/external-encryption.cpp index 6647ac4..3ecd74c 100644 --- a/lib/ode/external-encryption.cpp +++ b/lib/ode/external-encryption.cpp @@ -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(); - return external.changePassword(new_password, old_password); + return external.changePassword(old_password, new_password); } int ode_external_encryption_get_state(int* state) diff --git a/lib/ode/internal-encryption.cpp b/lib/ode/internal-encryption.cpp index c626e8d..696e7ae 100644 --- a/lib/ode/internal-encryption.cpp +++ b/lib/ode/internal-encryption.cpp @@ -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(); - return internal.changePassword(new_password, old_password); + return internal.changePassword(old_password, new_password); } int ode_internal_encryption_get_state(int* state) diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index 7287295..49d0d73 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -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 diff --git a/server/engine/dmcrypt-engine.cpp b/server/engine/dmcrypt-engine.cpp index 419e6c2..383b5cb 100644 --- a/server/engine/dmcrypt-engine.cpp +++ b/server/engine/dmcrypt-engine.cpp @@ -24,6 +24,8 @@ #include #include +#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 diff --git a/server/engine/dmcrypt-engine.h b/server/engine/dmcrypt-engine.h index 4a9c35b..7dd368d 100644 --- a/server/engine/dmcrypt-engine.h +++ b/server/engine/dmcrypt-engine.h @@ -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; diff --git a/server/engine/ecryptfs-engine.cpp b/server/engine/ecryptfs-engine.cpp index 0031d32..dd48a2e 100644 --- a/server/engine/ecryptfs-engine.cpp +++ b/server/engine/ecryptfs-engine.cpp @@ -17,6 +17,8 @@ #include #include +#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 diff --git a/server/engine/ecryptfs-engine.h b/server/engine/ecryptfs-engine.h index ba6029c..b0d5b44 100644 --- a/server/engine/ecryptfs-engine.h +++ b/server/engine/ecryptfs-engine.h @@ -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); diff --git a/server/engine/ext4-engine.cpp b/server/engine/ext4-engine.cpp old mode 100755 new mode 100644 index 59769d3..61e3a9f --- a/server/engine/ext4-engine.cpp +++ b/server/engine/ext4-engine.cpp @@ -13,13 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License */ -#include -#include -#include -#include - -#include "ext4-engine.h" -#include "../key-manager/key-generator.h" #include #include #include @@ -35,6 +28,16 @@ #include #include +#include +#include +#include +#include + +#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 diff --git a/server/engine/ext4-engine.h b/server/engine/ext4-engine.h old mode 100755 new mode 100644 index 661a248..80922a9 --- a/server/engine/ext4-engine.h +++ b/server/engine/ext4-engine.h @@ -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 data; - void mount(const data& key); + 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; diff --git a/server/external-encryption.cpp b/server/external-encryption.cpp index 98986cf..c5eed8c 100644 --- a/server/external-encryption.cpp +++ b/server/external-encryption.cpp @@ -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 index 0000000..3fd8e1c --- /dev/null +++ b/server/file-footer.cpp @@ -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 + +#include +#include + +#include +#include +#include + +#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 index 0000000..22fa6d0 --- /dev/null +++ b/server/file-footer.h @@ -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 +#include + +namespace ode { + +class FileFooter final { +public: + FileFooter() = delete; + + typedef std::vector 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__ diff --git a/server/internal-encryption.cpp b/server/internal-encryption.cpp index d6979df..9562530 100644 --- a/server/internal-encryption.cpp +++ b/server/internal-encryption.cpp @@ -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; } diff --git a/server/key-manager/key-generator.cpp b/server/key-manager/key-generator.cpp old mode 100755 new mode 100644 index b772db4..44a1a0e --- a/server/key-manager/key-generator.cpp +++ b/server/key-manager/key-generator.cpp @@ -27,51 +27,62 @@ #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(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(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(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(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(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; } diff --git a/server/key-manager/key-generator.h b/server/key-manager/key-generator.h old mode 100755 new mode 100644 index 1653d58..00a8dda --- a/server/key-manager/key-generator.h +++ b/server/key-manager/key-generator.h @@ -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 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 diff --git a/server/key-manager/key-manager.cpp b/server/key-manager/key-manager.cpp old mode 100755 new mode 100644 index a584197..2bff609 --- a/server/key-manager/key-manager.cpp +++ b/server/key-manager/key-manager.cpp @@ -13,12 +13,22 @@ * See the License for the specific language governing permissions and * limitations under the License */ +#include + #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 diff --git a/server/key-manager/key-manager.h b/server/key-manager/key-manager.h index 17db47f..b8138ba 100644 --- a/server/key-manager/key-manager.h +++ b/server/key-manager/key-manager.h @@ -18,13 +18,15 @@ #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 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 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 diff --git a/server/key-manager/key-store.cpp b/server/key-manager/key-store.cpp index 896de3f..e1aec0d 100644 --- a/server/key-manager/key-store.cpp +++ b/server/key-manager/key-store.cpp @@ -14,6 +14,7 @@ * limitations under the License */ #include +#include #include #include @@ -22,162 +23,170 @@ #include #include -#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 diff --git a/server/key-manager/key-store.h b/server/key-manager/key-store.h index ac67e85..e50c129 100644 --- a/server/key-manager/key-store.h +++ b/server/key-manager/key-store.h @@ -22,11 +22,16 @@ #include +#include "luks.h" + namespace ode { class KeyStore final { public: - KeyStore(const std::string &name); + typedef std::vector 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 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 index 0000000..c3fdf25 --- /dev/null +++ b/server/key-manager/luks.h @@ -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 + +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__ diff --git a/server/server.cpp b/server/server.cpp index 4a9cefe..e948ebb 100644 --- a/server/server.cpp +++ b/server/server.cpp @@ -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() diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 232d192..4fc8129 100755 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -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 -- 2.34.1