From: Krzysztof Jackiewicz Date: Thu, 9 Nov 2017 09:13:23 +0000 (+0100) Subject: Add framework for master key storage X-Git-Tag: submit/tizen/20171201.152910~12 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=5a22551715f7e607aa530f95c39f435114ce38ba;p=platform%2Fcore%2Fsecurity%2Fode.git Add framework for master key storage - Add wrapper for dlopen + dlsym + dlclose. - Add functions for master key management Change-Id: I6d988320e90e21aad9066899d3bd8ea14b41034c --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 229f1e6..51f5eb5 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -86,6 +86,15 @@ IF(NOT DEFINED SYSTEMD_UNIT_DIR) SET(SYSTEMD_UNIT_DIR "${CMAKE_INSTALL_PREFIX}/lib/systemd/system") ENDIF(NOT DEFINED SYSTEMD_UNIT_DIR) +IF(NOT DEFINED KEY_STORAGE_PLUGIN_DIR) + SET(KEY_STORAGE_PLUGIN_DIR "${CMAKE_INSTALL_LIBDIR}/ode-key-storage-plugin") +ENDIF(NOT DEFINED KEY_STORAGE_PLUGIN_DIR) + +SET(KEY_STORAGE_PLUGIN "key-storage-plugin") + +ADD_DEFINITIONS(-DKEY_STORAGE_PLUGIN_DIR="${KEY_STORAGE_PLUGIN_DIR}") +ADD_DEFINITIONS(-DKEY_STORAGE_PLUGIN_LIB="${CMAKE_SHARED_LIBRARY_PREFIX}${KEY_STORAGE_PLUGIN}${CMAKE_SHARED_LIBRARY_SUFFIX}") + ADD_DEFINITIONS(-DUG_WAYLAND) ADD_SUBDIRECTORY(${ODE_LIB}) diff --git a/packaging/ode.spec b/packaging/ode.spec index 75340c0..9ddb80b 100755 --- a/packaging/ode.spec +++ b/packaging/ode.spec @@ -22,6 +22,8 @@ BuildRequires: pkgconfig(openssl) BuildRequires: pkgconfig(libsmack) Requires: cryptsetup +%global key_storage_plugin_dir %{_libdir}/ode-key-storage-plugin/ + %description The ode package provides a daemon which is responsible for encrypting/decryption storages and secure erasing. @@ -33,6 +35,7 @@ The ode package provides a daemon which is responsible for encrypting/decryption %{_unitdir}/multi-user.target.wants/ode.service %attr(700,root,root) %{_sbindir}/ode-admin-cli %{_datadir}/%{name} +%dir %{key_storage_plugin_dir} %prep %setup -q @@ -51,7 +54,8 @@ The ode package provides a daemon which is responsible for encrypting/decryption -DBIN_DIR=%{TZ_SYS_BIN} \ -DSYSTEMD_UNIT_DIR=%{_unitdir} \ -DAPP_INSTALL_PREFIX="%{TZ_SYS_RO_APP}" \ - -DAPP_SHARE_PACKAGES_DIR="%{TZ_SYS_RO_PACKAGES}" + -DAPP_SHARE_PACKAGES_DIR="%{TZ_SYS_RO_PACKAGES}" \ + -DKEY_STORAGE_PLUGIN_DIR="%{key_storage_plugin_dir}" make %{?jobs:-j%jobs} diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index c51f696..2c115c9 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -37,6 +37,7 @@ SET(SERVER_SRCS main.cpp key-manager/key-generator.cpp key-manager/anti-forensics.cpp key-manager/encrypted-key.cpp + upgrade-support.cpp ) SET(DEPENDENCY klay @@ -60,7 +61,7 @@ PKG_CHECK_MODULES(SERVER_DEPS REQUIRED ${DEPENDENCY}) INCLUDE_DIRECTORIES(SYSTEM ${SERVER_DEPS_INCLUDE_DIRS} ${ODE_SERVER} ${PROJECT_SOURCE_DIR}) -TARGET_LINK_LIBRARIES(${SERVER_NAME} ${SERVER_DEPS_LIBRARIES} ${LFS_LDFLAGS} ${LFS_LIBS} pthread) +TARGET_LINK_LIBRARIES(${SERVER_NAME} ${SERVER_DEPS_LIBRARIES} ${LFS_LDFLAGS} ${LFS_LIBS} pthread dl) SET_TARGET_PROPERTIES(${SERVER_NAME} PROPERTIES COMPILE_FLAGS "-fPIE") SET_TARGET_PROPERTIES(${SERVER_NAME} PROPERTIES LINK_FLAGS "-pie") @@ -76,3 +77,4 @@ CONFIGURE_FILE(systemd/${PROJECT_NAME}.service.in systemd/${PROJECT_NAME}.servic INSTALL(TARGETS ${SERVER_NAME} DESTINATION ${BIN_DIR}) INSTALL(FILES systemd/${PROJECT_NAME}.service DESTINATION ${SYSTEMD_UNIT_DIR}) INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/engine/encryption/dummy_password DESTINATION ${PROJECT_DATA_DIR}) +INSTALL(DIRECTORY DESTINATION ${KEY_STORAGE_PLUGIN_DIR}) \ No newline at end of file diff --git a/server/upgrade-support.cpp b/server/upgrade-support.cpp new file mode 100644 index 0000000..0676337 --- /dev/null +++ b/server/upgrade-support.cpp @@ -0,0 +1,231 @@ +/* + * 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 + */ + +#include "upgrade-support.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +namespace ode { + +namespace { + +extern "C" { +typedef int(*KeyStoragePluginStoreFn)(const unsigned char*, size_t, + unsigned char**, size_t*); +typedef int(*KeyStoragePluginLoadFn)(const unsigned char*, size_t, + unsigned char**, size_t*); +typedef int(*KeyStoragePluginRemoveFn)(const unsigned char*, size_t); +} + +std::mutex opGuard; + +// not thread-safe because of static member +class KeyStoragePlugin { +public: + explicit KeyStoragePlugin(); + + KeyStoragePlugin(KeyStoragePlugin&&) = default; + + KeyStoragePlugin(const KeyStoragePlugin&) = delete; + KeyStoragePlugin& operator=(const KeyStoragePlugin&) = delete; + + ~KeyStoragePlugin(); + + static KeyStoragePlugin& Instance(); + + typedef std::vector Data; + + Data store(const Data& key); + Data load(const Data& token); + void remove(const Data& token); + +private: + void* so; + KeyStoragePluginStoreFn storeFn; + KeyStoragePluginLoadFn loadFn; + KeyStoragePluginRemoveFn removeFn; + + static std::unique_ptr plugin; +}; + +std::unique_ptr KeyStoragePlugin::plugin; + +KeyStoragePlugin& KeyStoragePlugin::Instance() +{ + if (!plugin) + plugin.reset(new KeyStoragePlugin()); + + return *plugin; +} + +KeyStoragePlugin::KeyStoragePlugin() : so(NULL) +{ + std::string path = std::string(KEY_STORAGE_PLUGIN_DIR) + "/" + KEY_STORAGE_PLUGIN_LIB; + + so = ::dlopen(path.c_str(), RTLD_LAZY); + if (so == NULL) + throw runtime::Exception(std::string("Failed to load library: ") + + path + ". Error: " + ::dlerror()); + + storeFn = reinterpret_cast(::dlsym(so, "ode_ksp_store")); + if (storeFn == NULL) + throw runtime::Exception( + std::string("ode_ksp_store() symbol not found. Error: ") + ::dlerror()); + + loadFn = reinterpret_cast(::dlsym(so, "ode_ksp_load")); + if (loadFn == NULL) + throw runtime::Exception( + std::string("ode_ksp_load() symbol not found. Error: ") + ::dlerror()); + + removeFn = reinterpret_cast(::dlsym(so, "ode_ksp_remove")); + if (removeFn == NULL) + throw runtime::Exception( + std::string("ode_ksp_remove() symbol not found. Error: ") + ::dlerror()); +} + +KeyStoragePlugin::~KeyStoragePlugin() +{ + ::dlclose(so); +} + +KeyStoragePlugin::Data KeyStoragePlugin::store(const KeyStoragePlugin::Data& key) +{ + unsigned char* token = NULL; + size_t token_len = 0; + int ret = storeFn(key.data(), key.size(), &token, &token_len); + if (ret != 0) + throw runtime::Exception(std::string("Storing the key failed with ") + + std::to_string(ret)); + + Data tokenVector(token, token + token_len); + free(token); + return tokenVector; +} + +KeyStoragePlugin::Data KeyStoragePlugin::load(const KeyStoragePlugin::Data& token) +{ + unsigned char* key = NULL; + size_t key_len = 0; + int ret = loadFn(token.data(), token.size(), &key, &key_len); + if (ret != 0) + throw runtime::Exception(std::string("Loading the key failed with ") + + std::to_string(ret)); + + Data keyVector(key, key + key_len); + free(key); + return keyVector; +} + +void KeyStoragePlugin::remove(const KeyStoragePlugin::Data& token) +{ + int ret = removeFn(token.data(), token.size()); + if (ret != 0) + throw runtime::Exception(std::string("Removing the key failed with ") + + std::to_string(ret)); +} + +std::string getTokenFileName(const std::string &device) +{ + std::string filename(device); + std::replace(filename.begin(), filename.end(), '/', '_'); + + return std::string("/opt/etc/.ode_token") + filename; +} + +void readToken(runtime::File &file, KeyStoragePlugin::Data& token) +{ + size_t tokenSize; + + file.open(O_RDONLY); + + file.read(&tokenSize, sizeof(tokenSize)); + token.resize(tokenSize); + file.read(token.data(), tokenSize); + + file.close(); +} + +void writeToken(runtime::File &file, const KeyStoragePlugin::Data& token) +{ + size_t tokenSize(token.size()); + + file.create(0600); + + file.write(&tokenSize, sizeof(tokenSize)); + file.write(token.data(), token.size()); + + file.close(); +} + +} // anonymous namespace + +namespace UpgradeSupport { + +void storeMasterKey(const std::string &device, const KeyStoragePlugin::Data& key) +{ + std::lock_guard lock(opGuard); + + auto& up = KeyStoragePlugin::Instance(); + auto token = up.store(key); + + runtime::File file(getTokenFileName(device)); + + writeToken(file, token); +} + +KeyStoragePlugin::Data loadMasterKey(const std::string &device) +{ + KeyStoragePlugin::Data token; + + std::lock_guard lock(opGuard); + + runtime::File file(getTokenFileName(device)); + readToken(file, token); + + auto& up = KeyStoragePlugin::Instance(); + return up.load(token); +} + +void removeMasterKey(const std::string &device) +{ + KeyStoragePlugin::Data token; + + std::lock_guard lock(opGuard); + + runtime::File file(getTokenFileName(device)); + readToken(file, token); + + auto& up = KeyStoragePlugin::Instance(); + up.remove(token); + + file.remove(); +} + +} // namespace UpgradeSupport + +} // namespace ode diff --git a/server/upgrade-support.h b/server/upgrade-support.h new file mode 100644 index 0000000..509576f --- /dev/null +++ b/server/upgrade-support.h @@ -0,0 +1,36 @@ +/* + * 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 + */ + +#ifndef __ODE_UPGRADE_SUPPORT_H__ +#define __ODE_UPGRADE_SUPPORT_H__ + +#include + +#include + +namespace ode { + +namespace UpgradeSupport { + +void storeMasterKey(const std::string &device, const Key::KeyData& key); +Key::KeyData loadMasterKey(const std::string &device); +void removeMasterKey(const std::string &device); + +} // namespace UpgradeSupport + +} // namespace ode + +#endif // __ODE_UPGRADE_SUPPORT_H__