From: Krzysztof Jackiewicz Date: Thu, 9 Nov 2017 09:44:48 +0000 (+0100) Subject: Use KeyServer for server side key managent X-Git-Tag: submit/tizen/20171201.152910~16 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=30df85ddeae9bc7b740577599abfa0bf9f76d1a8;p=platform%2Fcore%2Fsecurity%2Fode.git Use KeyServer for server side key managent - server side uses KeyServer for key management - refactor key management - use empty key value in EncryptedKey::decrypt() to differentiate wrong password from other errors Change-Id: I7e2c4c0af794309d85ad1182f3ab2a67412a16af --- diff --git a/rmi/key.h b/rmi/key.h index ceff714..1ae7012 100644 --- a/rmi/key.h +++ b/rmi/key.h @@ -18,6 +18,9 @@ #define __ODE_KEY_H__ #include +#include + +#include "common.h" namespace ode { @@ -31,6 +34,7 @@ public: DEFAULT_256BIT = 1, DEFAULT_512BIT = 2, }; + typedef std::vector KeyData; // TODO change it to something else outside of this class virtual ~Key() {} diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index efbc4f8..c51f696 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -34,9 +34,9 @@ SET(SERVER_SRCS main.cpp engine/erase/mmc-engine.cpp engine/erase/erase-engine.cpp key-manager/key-store.cpp - key-manager/key-manager.cpp key-manager/key-generator.cpp key-manager/anti-forensics.cpp + key-manager/encrypted-key.cpp ) SET(DEPENDENCY klay diff --git a/server/engine/encryption/cryptsetup-engine.cpp b/server/engine/encryption/cryptsetup-engine.cpp index ebce939..e325f2c 100644 --- a/server/engine/encryption/cryptsetup-engine.cpp +++ b/server/engine/encryption/cryptsetup-engine.cpp @@ -15,7 +15,6 @@ */ #include "cryptsetup-engine.h" -#include "../../file-footer.h" #include "../../logger.h" #include @@ -190,24 +189,4 @@ void CryptsetupEngine::close(const std::string &name) forkAndWrite(argv, NULL); } -bool CryptsetupEngine::isKeyMetaSet() -{ - return FileFooter::exist(devPath); -} - -const CryptsetupEngine::data CryptsetupEngine::getKeyMeta() -{ - return FileFooter::read(devPath); -} - -void CryptsetupEngine::setKeyMeta(const data &meta) -{ - FileFooter::write(devPath, meta); -} - -void CryptsetupEngine::clearKeyMeta() -{ - FileFooter::clear(devPath); -} - } // namespace ode diff --git a/server/engine/encryption/cryptsetup-engine.h b/server/engine/encryption/cryptsetup-engine.h index 0f6b644..263d7ba 100644 --- a/server/engine/encryption/cryptsetup-engine.h +++ b/server/engine/encryption/cryptsetup-engine.h @@ -70,11 +70,6 @@ public: static void close(const std::string &name); - bool isKeyMetaSet(); - const data getKeyMeta(); - void setKeyMeta(const data &data); - void clearKeyMeta(); - private: std::string devPath; }; diff --git a/server/engine/encryption/dmcrypt-engine.cpp b/server/engine/encryption/dmcrypt-engine.cpp index e6f8872..f6165f3 100644 --- a/server/engine/encryption/dmcrypt-engine.cpp +++ b/server/engine/encryption/dmcrypt-engine.cpp @@ -27,7 +27,6 @@ #include #include "../../logger.h" -#include "../../file-footer.h" #include "../../ext4-tool.h" #include "dmcrypt-engine.h" @@ -351,26 +350,6 @@ void DMCryptEngine::decrypt(const DMCryptEngine::data &key, unsigned int options progress.done(); } -bool DMCryptEngine::isKeyMetaSet() -{ - return FileFooter::exist(source); -} - -const DMCryptEngine::data DMCryptEngine::getKeyMeta() -{ - return FileFooter::read(source); -} - -void DMCryptEngine::setKeyMeta(const data &meta) -{ - FileFooter::write(source, meta); -} - -void DMCryptEngine::clearKeyMeta() -{ - FileFooter::clear(source); -} - unsigned int DMCryptEngine::getSupportedOptions() { return OPTION_INCLUDE_UNUSED_REGION; diff --git a/server/engine/encryption/dmcrypt-engine.h b/server/engine/encryption/dmcrypt-engine.h index 3c8d5f3..fed5f94 100644 --- a/server/engine/encryption/dmcrypt-engine.h +++ b/server/engine/encryption/dmcrypt-engine.h @@ -54,11 +54,6 @@ public: void encrypt(const data &key, unsigned int options); void decrypt(const data &key, unsigned int options); - bool isKeyMetaSet(); - const data getKeyMeta(); - void setKeyMeta(const data &data); - void clearKeyMeta(); - unsigned int getSupportedOptions(); private: diff --git a/server/engine/encryption/ecryptfs-engine.cpp b/server/engine/encryption/ecryptfs-engine.cpp index 4b87d9a..3fa613d 100644 --- a/server/engine/encryption/ecryptfs-engine.cpp +++ b/server/engine/encryption/ecryptfs-engine.cpp @@ -25,7 +25,6 @@ #include #include "../../kernel-keyring.h" -#include "../../file-footer.h" #include "../../logger.h" #include "ecryptfs-engine.h" @@ -453,26 +452,6 @@ void EcryptfsEngine::decrypt(const data &key, unsigned int options) progress.done(); } -bool EcryptfsEngine::isKeyMetaSet() -{ - return FileFooter::exist(source); -} - -const EcryptfsEngine::data EcryptfsEngine::getKeyMeta() -{ - return FileFooter::read(source); -} - -void EcryptfsEngine::setKeyMeta(const data &meta) -{ - FileFooter::write(source, meta); -} - -void EcryptfsEngine::clearKeyMeta() -{ - FileFooter::clear(source); -} - unsigned int EcryptfsEngine::getSupportedOptions() { return SUPPORTED_OPTIONS; diff --git a/server/engine/encryption/ecryptfs-engine.h b/server/engine/encryption/ecryptfs-engine.h index 96982e0..5e83dea 100644 --- a/server/engine/encryption/ecryptfs-engine.h +++ b/server/engine/encryption/ecryptfs-engine.h @@ -54,11 +54,6 @@ public: void encrypt(const data& key, unsigned int); void decrypt(const data& key, unsigned int); - bool isKeyMetaSet(); - const data getKeyMeta(); - void setKeyMeta(const data &data); - void clearKeyMeta(); - unsigned int getSupportedOptions(); private: diff --git a/server/engine/encryption/ext4-engine.cpp b/server/engine/encryption/ext4-engine.cpp index 908d841..7f771c0 100755 --- a/server/engine/encryption/ext4-engine.cpp +++ b/server/engine/encryption/ext4-engine.cpp @@ -33,7 +33,6 @@ #include "../../logger.h" #include "../../kernel-keyring.h" -#include "../../file-footer.h" #include "../../key-manager/key-generator.h" #include "ext4-engine.h" @@ -392,26 +391,6 @@ void Ext4Engine::decrypt(const Ext4Engine::data& key, unsigned int options) progress.done(); } -bool Ext4Engine::isKeyMetaSet() -{ - return FileFooter::exist(source); -} - -const Ext4Engine::data Ext4Engine::getKeyMeta() -{ - return FileFooter::read(source); -} - -void Ext4Engine::setKeyMeta(const data &data) -{ - FileFooter::write(source, data); -} - -void Ext4Engine::clearKeyMeta() -{ - FileFooter::clear(source); -} - unsigned int Ext4Engine::getSupportedOptions() { return 0; diff --git a/server/engine/encryption/ext4-engine.h b/server/engine/encryption/ext4-engine.h index f1aecec..dfd848d 100644 --- a/server/engine/encryption/ext4-engine.h +++ b/server/engine/encryption/ext4-engine.h @@ -54,11 +54,6 @@ public: void encrypt(const data &key, unsigned int options); void decrypt(const data &key, unsigned int options); - bool isKeyMetaSet(); - const data getKeyMeta(); - void setKeyMeta(const data &data); - void clearKeyMeta(); - unsigned int getSupportedOptions(); private: diff --git a/server/external-encryption.cpp b/server/external-encryption.cpp index 5b0452d..fe1169b 100644 --- a/server/external-encryption.cpp +++ b/server/external-encryption.cpp @@ -32,6 +32,7 @@ #include "app-bundle.h" #include "progress-bar.h" #include "rmi/common.h" +#include "file-footer.h" #include "external-encryption.h" @@ -181,8 +182,10 @@ void setOptions(unsigned int options) } // namsepace -ExternalEncryptionServer::ExternalEncryptionServer(ServerContext &srv) : - server(srv) +ExternalEncryptionServer::ExternalEncryptionServer(ServerContext &srv, + KeyServer& key) : + server(srv), + keyServer(key) { server.expose(this, PRIVILEGE_PLATFORM, (int)(ExternalEncryptionServer::setMountPassword)(std::string)); server.expose(this, PRIVILEGE_PLATFORM, (int)(ExternalEncryptionServer::mount)()); @@ -216,16 +219,7 @@ ExternalEncryptionServer::~ExternalEncryptionServer() int ExternalEncryptionServer::setMountPassword(const std::string& password) { - KeyManager::data pwData(password.begin(), password.end()); - KeyManager keyManager(engine->getKeyMeta()); - if (!keyManager.verifyPassword(pwData)) { - ERROR(SINK, "Wrong password passed."); - return error::WrongPassword; - } - - mountKey = keyManager.getMasterKey(pwData); - - return error::None; + return keyServer.get(engine->getSource(), password, mountKey); } int ExternalEncryptionServer::mount() @@ -235,7 +229,7 @@ int ExternalEncryptionServer::mount() return error::NoData; } - KeyManager::data key = mountKey; + Key::KeyData key = mountKey; mountKey.clear(); if (getState() != State::Encrypted) { @@ -294,22 +288,18 @@ int ExternalEncryptionServer::encrypt(const std::string &password, unsigned int return error::NoSuchDevice; } - KeyManager::data pwData(password.begin(), password.end()); - KeyManager keyManager(engine->getKeyMeta()); - - if (!keyManager.verifyPassword(pwData)) { - ERROR(SINK, "Wrong password passed."); - return error::WrongPassword; - } + Key::KeyData masterKey; + int ret = keyServer.get(engine->getSource(), password, masterKey); + if (ret != error::None) + return ret; - KeyManager::data MasterKey = keyManager.getMasterKey(pwData); - auto encryptWorker = [MasterKey, options, this]() { + auto encryptWorker = [masterKey, options, this]() { try { INFO(SINK, "Closing all applications using external storage."); killDependentApplications(EXTERNAL_PATH); INFO(SINK, "Encryption started."); - engine->encrypt(MasterKey, options); + engine->encrypt(masterKey, options); setOptions(options & getSupportedOptions()); INFO(SINK, "Encryption completed."); @@ -337,16 +327,12 @@ int ExternalEncryptionServer::decrypt(const std::string &password) return error::NoSuchDevice; } - KeyManager::data pwData(password.begin(), password.end()); - KeyManager keyManager(engine->getKeyMeta()); + Key::KeyData masterKey; + int ret = keyServer.get(engine->getSource(), password, masterKey); + if (ret != error::None) + return ret; - if (!keyManager.verifyPassword(pwData)) { - ERROR(SINK, "Wrong password passed."); - return error::WrongPassword; - } - - KeyManager::data MasterKey = keyManager.getMasterKey(pwData); - auto decryptWorker = [MasterKey, this]() { + auto decryptWorker = [masterKey, this]() { try { INFO(SINK, "Closing all applications using external storage."); killDependentApplications(EXTERNAL_PATH); @@ -363,7 +349,7 @@ int ExternalEncryptionServer::decrypt(const std::string &password) INFO(SINK, "Decryption started."); ::vconf_set_str(VCONFKEY_SDE_CRYPTO_STATE, "error_partially_encrypted"); - engine->decrypt(MasterKey, getOptions()); + engine->decrypt(masterKey, getOptions()); INFO(SINK, "Decryption completed."); ::vconf_set_str(VCONFKEY_SDE_CRYPTO_STATE, "unencrypted"); @@ -392,7 +378,7 @@ int ExternalEncryptionServer::recovery() iter->remove(true); } - engine->clearKeyMeta(); + keyServer.removePassword(engine->getSource()); ::vconf_set_str(VCONFKEY_SDE_CRYPTO_STATE, "unencrypted"); return error::None; @@ -400,63 +386,28 @@ int ExternalEncryptionServer::recovery() int ExternalEncryptionServer::isPasswordInitialized() { - if (engine->isKeyMetaSet()) { - return error::None; - } - return error::NoSuchFile; + return keyServer.isInitialized(engine->getSource()); } int ExternalEncryptionServer::initPassword(const std::string& password) { - KeyManager::data pwData(password.begin(), password.end()); - KeyManager keyManager; - - keyManager.initPassword(pwData); - engine->setKeyMeta(keyManager.serialize()); - return error::None; + return keyServer.init(engine->getSource(), password, Key::DEFAULT_256BIT); } int ExternalEncryptionServer::cleanPassword(const std::string& password) { - KeyManager::data pwData(password.begin(), password.end()); - KeyManager keyManager(engine->getKeyMeta()); - - if (!keyManager.verifyPassword(pwData)) { - ERROR(SINK, "Wrong password passed."); - return error::WrongPassword; - } - - engine->clearKeyMeta(); - return error::None; + return keyServer.remove(engine->getSource(), password); } int ExternalEncryptionServer::changePassword(const std::string &oldPassword, - const std::string &newPassword) + const std::string &newPassword) { - KeyManager::data oldPwData(oldPassword.begin(), oldPassword.end()); - KeyManager::data newPwData(newPassword.begin(), newPassword.end()); - KeyManager keyManager(engine->getKeyMeta()); - - if (!keyManager.verifyPassword(oldPwData)) { - ERROR(SINK, "Wrong password passed."); - return error::WrongPassword; - } - - keyManager.changePassword(oldPwData, newPwData); - engine->setKeyMeta(keyManager.serialize()); - - return error::None; + return keyServer.changePassword(engine->getSource(), oldPassword, newPassword); } int ExternalEncryptionServer::verifyPassword(const std::string& password) { - KeyManager::data pwData(password.begin(), password.end()); - KeyManager keyManager(engine->getKeyMeta()); - - if (keyManager.verifyPassword(pwData)) { - return error::None; - } - return error::WrongPassword; + return keyServer.verifyPassword(engine->getSource(), password); } int ExternalEncryptionServer::getState() diff --git a/server/external-encryption.h b/server/external-encryption.h index 15ba976..0d614b4 100644 --- a/server/external-encryption.h +++ b/server/external-encryption.h @@ -24,7 +24,7 @@ #include #include "rmi/external-encryption.h" -#include "key-manager/key-manager.h" +#include "key-server.h" #include "engine/encryption/ecryptfs-engine.h" #include "server.h" @@ -34,7 +34,7 @@ typedef EcryptfsEngine EXTERNAL_ENGINE; class ExternalEncryptionServer final: public ExternalEncryption { public: - ExternalEncryptionServer(ServerContext& srv); + ExternalEncryptionServer(ServerContext& srv, KeyServer& key); ~ExternalEncryptionServer(); int setMountPassword(const std::string& password); @@ -61,7 +61,8 @@ private: ServerContext& server; std::unique_ptr engine; - KeyManager::data mountKey; + Key::KeyData mountKey; + KeyServer& keyServer; }; } // namespace ode diff --git a/server/internal-encryption.cpp b/server/internal-encryption.cpp index 6bb2b28..6a5dd36 100644 --- a/server/internal-encryption.cpp +++ b/server/internal-encryption.cpp @@ -232,8 +232,10 @@ void setOptions(unsigned int options) } -InternalEncryptionServer::InternalEncryptionServer(ServerContext& srv) : - server(srv) +InternalEncryptionServer::InternalEncryptionServer(ServerContext& srv, + KeyServer& key) : + server(srv), + keyServer(key) { server.expose(this, PRIVILEGE_PLATFORM, (int)(InternalEncryptionServer::setMountPassword)(std::string)); server.expose(this, PRIVILEGE_PLATFORM, (int)(InternalEncryptionServer::mount)()); @@ -267,16 +269,7 @@ InternalEncryptionServer::~InternalEncryptionServer() int InternalEncryptionServer::setMountPassword(const std::string& password) { - KeyManager::data pwData(password.begin(), password.end()); - KeyManager keyManager(engine->getKeyMeta()); - if (!keyManager.verifyPassword(pwData)) { - ERROR(SINK, "Wrong password passed."); - return error::WrongPassword; - } - - mountKey = keyManager.getMasterKey(pwData); - - return error::None; + return keyServer.get(engine->getSource(), password, mountKey); } int InternalEncryptionServer::mount() @@ -286,7 +279,7 @@ int InternalEncryptionServer::mount() return error::NoData; } - KeyManager::data key = mountKey; + Key::KeyData key = mountKey; mountKey.clear(); if (getState() != State::Encrypted) { @@ -347,16 +340,12 @@ int InternalEncryptionServer::encrypt(const std::string& password, unsigned int return error::NoSuchDevice; } - KeyManager::data pwData(password.begin(), password.end()); - KeyManager keyManager(engine->getKeyMeta()); - - if (!keyManager.verifyPassword(pwData)) { - ERROR(SINK, "Wrong password passed."); - return error::WrongPassword; - } + Key::KeyData masterKey; + int ret = keyServer.get(engine->getSource(), password, masterKey); + if (ret != error::None) + return ret; - KeyManager::data MasterKey = keyManager.getMasterKey(pwData); - auto encryptWorker = [MasterKey, options, this]() { + auto encryptWorker = [masterKey, options, this]() { try { std::string source = engine->getSource(); std::string mntPath = findMountPointByDevice(source); @@ -383,7 +372,7 @@ int InternalEncryptionServer::encrypt(const std::string& password, unsigned int INFO(SINK, "Encryption started."); ::vconf_set_str(VCONFKEY_ODE_CRYPTO_STATE, "error_partially_encrypted"); - engine->encrypt(MasterKey, options); + engine->encrypt(masterKey, options); setOptions(options & getSupportedOptions()); INFO(SINK, "Encryption completed."); @@ -411,16 +400,12 @@ int InternalEncryptionServer::decrypt(const std::string& password) return error::NoSuchDevice; } - KeyManager::data pwData(password.begin(), password.end()); - KeyManager keyManager(engine->getKeyMeta()); + Key::KeyData masterKey; + int ret = keyServer.get(engine->getSource(), password, masterKey); + if (ret != error::None) + return ret; - if (!keyManager.verifyPassword(pwData)) { - ERROR(SINK, "Wrong password passed."); - return error::WrongPassword; - } - - KeyManager::data MasterKey = keyManager.getMasterKey(pwData); - auto decryptWorker = [MasterKey, this]() { + auto decryptWorker = [masterKey, this]() { try { if (engine->isMounted()) { INFO(SINK, "Closing all known systemd services that might be using internal storage."); @@ -443,7 +428,7 @@ int InternalEncryptionServer::decrypt(const std::string& password) INFO(SINK, "Decryption started."); ::vconf_set_str(VCONFKEY_ODE_CRYPTO_STATE, "error_partially_encrypted"); - engine->decrypt(MasterKey, getOptions()); + engine->decrypt(masterKey, getOptions()); INFO(SINK, "Decryption complete."); ::vconf_set_str(VCONFKEY_ODE_CRYPTO_STATE, "unencrypted"); @@ -480,63 +465,28 @@ int InternalEncryptionServer::recovery() int InternalEncryptionServer::isPasswordInitialized() { - if (engine->isKeyMetaSet()) { - return error::None; - } - return error::NoSuchFile; + return keyServer.isInitialized(engine->getSource()); } int InternalEncryptionServer::initPassword(const std::string& password) { - KeyManager::data pwData(password.begin(), password.end()); - KeyManager keyManager; - - keyManager.initPassword(pwData); - engine->setKeyMeta(keyManager.serialize()); - return error::None; + return keyServer.init(engine->getSource(), password, Key::DEFAULT_256BIT); } int InternalEncryptionServer::cleanPassword(const std::string& password) { - KeyManager::data pwData(password.begin(), password.end()); - KeyManager keyManager(engine->getKeyMeta()); - - if (!keyManager.verifyPassword(pwData)) { - ERROR(SINK, "Wrong password passed."); - return error::WrongPassword; - } - - engine->clearKeyMeta(); - return error::None; + return keyServer.remove(engine->getSource(), password); } int InternalEncryptionServer::changePassword(const std::string& oldPassword, const std::string& newPassword) { - KeyManager::data oldPwData(oldPassword.begin(), oldPassword.end()); - KeyManager::data newPwData(newPassword.begin(), newPassword.end()); - KeyManager keyManager(engine->getKeyMeta()); - - if (!keyManager.verifyPassword(oldPwData)) { - ERROR(SINK, "Wrong password passed."); - return error::WrongPassword; - } - - keyManager.changePassword(oldPwData, newPwData); - engine->setKeyMeta(keyManager.serialize()); - - return error::None; + return keyServer.changePassword(engine->getSource(), oldPassword, newPassword); } int InternalEncryptionServer::verifyPassword(const std::string& password) { - KeyManager::data pwData(password.begin(), password.end()); - KeyManager keyManager(engine->getKeyMeta()); - - if (keyManager.verifyPassword(pwData)) { - return error::None; - } - return error::WrongPassword; + return keyServer.verifyPassword(engine->getSource(), password); } int InternalEncryptionServer::getState() diff --git a/server/internal-encryption.h b/server/internal-encryption.h index 57de876..cdb0236 100644 --- a/server/internal-encryption.h +++ b/server/internal-encryption.h @@ -21,7 +21,7 @@ #include #include "rmi/internal-encryption.h" -#include "key-manager/key-manager.h" +#include "key-server.h" #include "engine/encryption/dmcrypt-engine.h" #include "server.h" @@ -31,7 +31,7 @@ typedef DMCryptEngine INTERNAL_ENGINE; class InternalEncryptionServer final: public InternalEncryption { public: - InternalEncryptionServer(ServerContext& srv); + InternalEncryptionServer(ServerContext& srv, KeyServer& key); ~InternalEncryptionServer(); int setMountPassword(const std::string& password); @@ -58,7 +58,8 @@ private: ServerContext& server; std::unique_ptr engine; - KeyManager::data mountKey; + Key::KeyData mountKey; + KeyServer& keyServer; }; } // namespace ode diff --git a/server/key-manager/encrypted-key.cpp b/server/key-manager/encrypted-key.cpp new file mode 100644 index 0000000..fdf43ee --- /dev/null +++ b/server/key-manager/encrypted-key.cpp @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2017 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 + */ +/* + * @file encrypted-key.cpp + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @version 1.0 + */ + +#include "encrypted-key.h" + +#include "key-generator.h" +#include "anti-forensics.h" + +using namespace ode; + +namespace { +const size_t MK_DIGEST_ITERATIONS = 1000; +const size_t PW_DIGEST_ITERATIONS = 1000; +const size_t LUKS_STRIPES = 3; +} // anonymous namespace + +EncryptedKey::EncryptedKey(const Key::KeyData& masterKey, + const std::string& password) +{ + /* + * TODO These 3 values are unused. Read them in decrypt() and use + * proper algorithms to obtain the key + */ + store.setCipherName("aes"); + store.setCipherMode("cbc-essiv:sha256"); + store.setHashSpec("sha256"); + + store.setMasterKeyLength(masterKey.size()); + + auto masterKeyDigestSalt = KeyGenerator::RNG(store.getMasterKeyDigestSaltLength()); + store.setMasterKeyDigestSalt(masterKeyDigestSalt); + + store.setMasterKeyDigestIteration(MK_DIGEST_ITERATIONS); + auto masterKeyDigest = KeyGenerator::PBKDF(masterKey, + masterKeyDigestSalt, + store.getMasterKeyDigestIteration(), + store.getMasterKeyDigestLength()); + store.setMasterKeyDigest(std::move(masterKeyDigest)); + + encrypt(masterKey, password); +} + +Key::KeyData EncryptedKey::decrypt(const std::string& password) const +{ + Key::KeyData pwData(password.begin(), password.end()); + + auto derivedPassword = KeyGenerator::PBKDF(pwData, + store.getPasswordSalt(), + store.getPasswordIteration(), + store.getMasterKeyLength()); + + auto splittedMasterKey = KeyGenerator::AESDecrypt(store.getEncryptedMasterKey(), + derivedPassword, + KeyGenerator::SHA256(derivedPassword)); + + auto masterKeyCandidate = AntiForensics::AFMerge(splittedMasterKey, + store.getMasterKeyLength(), + LUKS_STRIPES); + + auto masterKeyCandidateDigest = KeyGenerator::PBKDF(masterKeyCandidate, + store.getMasterKeyDigestSalt(), + store.getMasterKeyDigestIteration(), + store.getMasterKeyDigestLength()); + + if (masterKeyCandidateDigest == store.getMasterKeyDigest()) + return masterKeyCandidate; + + // TODO consider using an exception when we have more than one type + return Key::KeyData(); +} + +void EncryptedKey::encrypt(const Key::KeyData& masterKey, + const std::string& password) +{ + Key::KeyData pwData(password.begin(), password.end()); + + auto passwordSalt = KeyGenerator::RNG(store.getPasswordSaltLength()); + store.setPasswordSalt(passwordSalt); + + store.setPasswordIteration(PW_DIGEST_ITERATIONS); + auto derivedPassword = KeyGenerator::PBKDF(pwData, + store.getPasswordSalt(), + store.getPasswordIteration(), + store.getMasterKeyLength()); + + auto splittedMasterKey = AntiForensics::AFSplit(masterKey, + masterKey.size(), + LUKS_STRIPES); + + auto encryptedMasterKey = KeyGenerator::AESEncrypt(splittedMasterKey, + derivedPassword, + KeyGenerator::SHA256(derivedPassword)); + store.setEncryptedMasterKey(encryptedMasterKey); +} diff --git a/server/key-manager/encrypted-key.h b/server/key-manager/encrypted-key.h new file mode 100644 index 0000000..9344035 --- /dev/null +++ b/server/key-manager/encrypted-key.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2017 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 + */ +/* + * @file encrypted-key.h + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @version 1.0 + */ + +#ifndef __ENCRYPTED_KEY__ +#define __ENCRYPTED_KEY__ + +#include "../file-footer.h" +#include "rmi/key.h" +#include "key-store.h" + +#include + +namespace ode { + +class EncryptedKey { +public: + EncryptedKey(const Key::KeyData& masterKey, const std::string& password); + explicit EncryptedKey(const FileFooter::data& footer) : store(footer) {} + + void encrypt(const Key::KeyData& masterKey, const std::string& password); + Key::KeyData decrypt(const std::string& password) const; + + FileFooter::data serialize() const { return store.serialize(); } +private: + KeyStore store; +}; + +} // namespace ode + +#endif // __ENCRYPTED_KEY__ diff --git a/server/key-manager/key-manager.cpp b/server/key-manager/key-manager.cpp deleted file mode 100644 index ad75c7d..0000000 --- a/server/key-manager/key-manager.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (c) 2015 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 "key-manager.h" -#include "key-generator.h" -#include "anti-forensics.h" - -#define ITERATION_COUNT 1000 -#define LUKS_STRIPES 3 - -namespace ode { - -KeyManager::KeyManager() -{ -} - -KeyManager::KeyManager(const data& data) : - store(data) -{ -} - -KeyManager::~KeyManager() -{ -} - -const KeyManager::data KeyManager::serialize() const -{ - return store.serialize(); -} - -const KeyManager::data KeyManager::newMasterKey(size_t keyBytes) -{ - data masterKey = KeyGenerator::RNG(keyBytes); - data masterKeyDigestSalt = KeyGenerator::RNG(store.getMasterKeyDigestSaltLength()); - - store.setMasterKeyLength(masterKey.size()); - - store.setMasterKeyDigestSalt(masterKeyDigestSalt); - store.setMasterKeyDigestIteration(ITERATION_COUNT); - store.setMasterKeyDigest(KeyGenerator::PBKDF(masterKey, - masterKeyDigestSalt, - store.getMasterKeyDigestIteration(), - store.getMasterKeyDigestLength())); - - return masterKey; -} - -const KeyManager::data KeyManager::getMasterKey(const data& password) const -{ - data derivedPassword = KeyGenerator::PBKDF(password, - store.getPasswordSalt(), - store.getPasswordIteration(), - store.getMasterKeyLength()); - - data splittedMasterKey = KeyGenerator::AESDecrypt( - store.getEncryptedMasterKey(), - derivedPassword, - KeyGenerator::SHA256(derivedPassword)); - - data masterKeyCandidate = AntiForensics::AFMerge(splittedMasterKey, store.getMasterKeyLength(), LUKS_STRIPES); - - data masterKeyCandidateDigest = KeyGenerator::PBKDF(masterKeyCandidate, - store.getMasterKeyDigestSalt(), - store.getMasterKeyDigestIteration(), - store.getMasterKeyDigestLength()); - - if (masterKeyCandidateDigest == store.getMasterKeyDigest()) { - return masterKeyCandidate; - } - - throw runtime::Exception("Password doesn't match!"); -} - -void KeyManager::setPassword(const data& masterKey, const data& password) { - data passwordSalt = KeyGenerator::RNG(store.getPasswordSaltLength()); - - store.setPasswordSalt(passwordSalt); - store.setPasswordIteration(ITERATION_COUNT); - - data derivedPassword = KeyGenerator::PBKDF(password, - store.getPasswordSalt(), - store.getPasswordIteration(), - store.getMasterKeyLength()); - - data splittedMasterKey = AntiForensics::AFSplit(masterKey, masterKey.size(), LUKS_STRIPES); - - store.setEncryptedMasterKey(KeyGenerator::AESEncrypt( - splittedMasterKey, - derivedPassword, - KeyGenerator::SHA256(derivedPassword))); -} - -void KeyManager::initPassword(const data& password, size_t keyBytes) -{ - store.setCipherName("aes"); - store.setCipherMode("cbc-essiv:sha256"); - store.setHashSpec("sha256"); - - setPassword(newMasterKey(keyBytes), password); -} - -void KeyManager::changePassword(const data& old_password, - const data& new_password) -{ - try { - setPassword(getMasterKey(old_password), new_password); - } catch (runtime::Exception &e) { - throw runtime::Exception("Password doesn't match!"); - } -} - -bool KeyManager::verifyPassword(const data& password) const -{ - 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 deleted file mode 100644 index 9eb44e7..0000000 --- a/server/key-manager/key-manager.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2015 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 __KEY_MANAGER_H__ -#define __KEY_MANAGER_H__ - -#include "key-store.h" - -namespace ode { - -class KeyManager final { -public: - typedef std::vector data; - - KeyManager(); - KeyManager(const data&); - KeyManager(const KeyManager&) = delete; - KeyManager(KeyManager&&) = delete; - ~KeyManager(); - - KeyManager& operator=(const KeyManager&) = delete; - KeyManager& operator=(KeyManager&&) = delete; - - const data serialize() const; - - const data getMasterKey(const data& password) const; - void setPassword(const data& masterKey, const data& password); - - void initPassword(const data& password, size_t keyBytes = DEFAULT_KEY_LENGTH); - void changePassword(const data& old_password, const data& new_password); - bool verifyPassword(const data& password) const; - -private: - // default master key length in bytes - static const size_t DEFAULT_KEY_LENGTH = 32; - - const data newMasterKey(size_t keyBytes); - - KeyStore store; -}; - -} // namespace ode - -#endif // __KEY_MANAGER_H__ diff --git a/server/key-server.cpp b/server/key-server.cpp index a7d4a69..7cf3cec 100644 --- a/server/key-server.cpp +++ b/server/key-server.cpp @@ -19,13 +19,17 @@ #include #include #include +#include #include "key-server.h" #include "file-footer.h" #include "logger.h" -#include "key-manager/key-manager.h" #include "misc.h" #include "rmi/common.h" +#include "key-manager/encrypted-key.h" +#include "key-manager/key-generator.h" + +#include namespace ode { @@ -65,30 +69,34 @@ int KeyServer::isInitialized(const std::string& dev) int KeyServer::init(const std::string& dev, const std::string& password, int params) +{ + KeyData dummy; + return initAndGet(dev, password, params, dummy); +} + +int KeyServer::initAndGet(const std::string& dev, + const std::string& password, + int params, + KeyData& masterKey) { if (dev.empty() || password.empty() || KEY_SIZE.find(params) == KEY_SIZE.end()) return error::InvalidParameter; - KeyManager::data pwData(password.begin(), password.end()); - KeyManager keyManager; + masterKey = KeyGenerator::RNG(KEY_SIZE.at(params)); - keyManager.initPassword(pwData, KEY_SIZE.at(params)); + EncryptedKey ek(masterKey, password); + FileFooter::write(dev, ek.serialize()); - FileFooter::write(dev, keyManager.serialize()); return error::None; } int KeyServer::remove(const std::string& dev, const std::string& password) { - if (dev.empty() || password.empty()) - return error::InvalidParameter; - - KeyManager::data pwData(password.begin(), password.end()); - KeyManager keyManager(FileFooter::read(dev)); - - if (!keyManager.verifyPassword(pwData)) { - ERROR(SINK, "Wrong password passed."); - return error::WrongPassword; + int ret = verifyPassword(dev, password); + if (ret != error::None) { + if (ret == error::WrongPassword) + ERROR(SINK, "Wrong password passed."); + return ret; } FileFooter::clear(dev); @@ -102,17 +110,21 @@ int KeyServer::changePassword(const std::string& dev, if (dev.empty() || curPassword.empty() || newPassword.empty()) return error::InvalidParameter; - KeyManager::data curPwData(curPassword.begin(), curPassword.end()); - KeyManager::data newPwData(newPassword.begin(), newPassword.end()); - KeyManager keyManager(FileFooter::read(dev)); + if (!FileFooter::exist(dev)) { + ERROR(SINK, "Given device has no master key"); + return error::NoSuchFile; + } + + EncryptedKey ek(FileFooter::read(dev)); - if (!keyManager.verifyPassword(curPwData)) { - ERROR(SINK, "Wrong password passed."); + auto key = ek.decrypt(curPassword); + if (key.empty()) { + ERROR(SINK, "Wrong password passed"); return error::WrongPassword; } + ek.encrypt(key, newPassword); - keyManager.changePassword(curPwData, newPwData); - FileFooter::write(dev, keyManager.serialize()); + FileFooter::write(dev, ek.serialize()); return error::None; } @@ -122,10 +134,48 @@ int KeyServer::verifyPassword(const std::string& dev, if (dev.empty() || password.empty()) return error::InvalidParameter; - KeyManager::data pwData(password.begin(), password.end()); - KeyManager keyManager(FileFooter::read(dev)); + if (!FileFooter::exist(dev)) { + ERROR(SINK, "Given device has no master key"); + return error::NoSuchFile; + } + + EncryptedKey ek(FileFooter::read(dev)); + + auto key = ek.decrypt(password); + if (key.empty()) + return error::WrongPassword; + + return error::None; +} + +int KeyServer::get(const std::string& dev, + const std::string& password, + KeyData& masterKey) const +{ + if (dev.empty() || password.empty()) + return error::InvalidParameter; + + if (!FileFooter::exist(dev)) { + ERROR(SINK, "Given device has no master key"); + return error::NoSuchFile; + } + + EncryptedKey ek(FileFooter::read(dev)); - return keyManager.verifyPassword(pwData) ? error::None : error::WrongPassword; + masterKey = ek.decrypt(password); + if (masterKey.empty()) { + ERROR(SINK, "Wrong password passed"); + return error::WrongPassword; + } + return error::None; +} + +void KeyServer::removePassword(const std::string& dev) +{ + if (dev.empty()) + return; + + FileFooter::clear(dev); } } // namespace ode diff --git a/server/key-server.h b/server/key-server.h index e44eebb..763282d 100644 --- a/server/key-server.h +++ b/server/key-server.h @@ -31,11 +31,19 @@ public: int isInitialized(const std::string& dev); int init(const std::string& dev, const std::string& password, int params); + int initAndGet(const std::string& dev, + const std::string& password, + int params, + KeyData& masterKey); int remove(const std::string& dev, const std::string& password); int changePassword(const std::string& dev, const std::string& curPW, const std::string& newPW); int verifyPassword(const std::string& dev, const std::string& password); + int get(const std::string& dev, + const std::string& password, + KeyData& masterKey) const; + void removePassword(const std::string& dev); private: ServerContext& server; diff --git a/server/luks.cpp b/server/luks.cpp index 4690cbe..8fcbeeb 100644 --- a/server/luks.cpp +++ b/server/luks.cpp @@ -20,7 +20,6 @@ #include "logger.h" #include "luks.h" -#include "key-manager/key-manager.h" #include "engine/encryption/cryptsetup-engine.h" #include "rmi/common.h" @@ -28,7 +27,6 @@ namespace ode { namespace { const char *PRIVILEGE_PLATFORM = "http://tizen.org/privilege/internal/default/platform"; -const size_t DEFAULT_KEY_SIZE = 64; std::map OPERATION_NAME = { { Luks::Format, "Formatting" }, @@ -47,7 +45,9 @@ std::map CRYPTSETUP_ERROR_2_ODE_ERROR = { } // anonymous namespace -LuksServer::LuksServer(ServerContext &srv) : server(srv) +LuksServer::LuksServer(ServerContext &srv, KeyServer& key) : + server(srv), + keyServer(key) { server.expose(this, PRIVILEGE_PLATFORM, (int)(LuksServer::format)(bool, std::string, std::string)); server.expose(this, PRIVILEGE_PLATFORM, (int)(LuksServer::open)(bool, std::string, std::string, std::string)); @@ -105,15 +105,13 @@ int LuksServer::format(bool sync, const std::string& password) { return execute(sync, Luks::Format, [=](){ - KeyManager::data pwData(password.begin(), password.end()); - KeyManager keyManager; - keyManager.initPassword(pwData, DEFAULT_KEY_SIZE); + Key::KeyData key; + int ret = keyServer.initAndGet(device, password, Key::DEFAULT_512BIT, key); + if (ret != error::None) + return ret; CryptsetupEngine engine(device); - engine.setKeyMeta(keyManager.serialize()); - - engine.format(CryptsetupEngine::DeviceType::LUKS, - keyManager.getMasterKey(pwData)); + engine.format(CryptsetupEngine::DeviceType::LUKS, key); return error::None; }); } @@ -126,16 +124,12 @@ int LuksServer::open(bool sync, return execute(sync, Luks::Open, [=](){ CryptsetupEngine engine(device); - KeyManager::data pwData(password.begin(), password.end()); - KeyManager keyManager(engine.getKeyMeta()); - - if (!keyManager.verifyPassword(pwData)) { - ERROR(SINK, "Wrong password passed."); - return error::WrongPassword; - } + Key::KeyData key; + int ret = keyServer.get(device, password, key); + if (ret != error::None) + return ret; - KeyManager::data masterKey = keyManager.getMasterKey(pwData); - engine.open(CryptsetupEngine::DeviceType::LUKS, mapping, masterKey); + engine.open(CryptsetupEngine::DeviceType::LUKS, mapping, key); return error::None; }); } diff --git a/server/luks.h b/server/luks.h index 772a9b2..821db2f 100644 --- a/server/luks.h +++ b/server/luks.h @@ -21,13 +21,14 @@ #include #include "rmi/luks.h" +#include "key-server.h" #include "server.h" namespace ode { class LuksServer final: public Luks { public: - explicit LuksServer(ServerContext& srv); + explicit LuksServer(ServerContext& srv, KeyServer& key); ~LuksServer(); int format(bool sync, @@ -46,6 +47,7 @@ private: int execute(bool sync, Luks::Operation op, const F& job); ServerContext& server; + KeyServer& keyServer; std::mutex opGuard; }; diff --git a/server/server.cpp b/server/server.cpp index 64bc609..2a58071 100644 --- a/server/server.cpp +++ b/server/server.cpp @@ -53,12 +53,13 @@ ServerContext::ServerContext() : rmi::Service(ODE_MANAGER_ADDRESS) expose(this, "", (runtime::FileDescriptor)(ServerContext::registerNotificationSubscriber)(std::string)); expose(this, "", (int)(ServerContext::unregisterNotificationSubscriber)(std::string, int)); - secureErase.reset(new SecureEraseServer(*this)); - internalEncryption.reset(new InternalEncryptionServer(*this)); - externalEncryption.reset(new ExternalEncryptionServer(*this)); - luks.reset(new LuksServer(*this)); keys.reset(new KeyServer(*this)); + secureErase.reset(new SecureEraseServer(*this)); + internalEncryption.reset(new InternalEncryptionServer(*this, *keys)); + externalEncryption.reset(new ExternalEncryptionServer(*this, *keys)); + luks.reset(new LuksServer(*this, *keys)); + KeyGenerator::init(); }