#include <sys/reboot.h>
#include <vconf.h>
+#include <tzplatform_config.h>
#include <klay/process.h>
#include <klay/file-user.h>
#include <klay/filesystem.h>
#include <klay/dbus/connection.h>
#include <klay/audit/logger.h>
-#include "engine/dmcrypt-engine.h"
+#include "vconf.h"
+#include "progress-bar.h"
+#include "engine/encryption/dmcrypt-engine.h"
#include "key-manager/key-manager.h"
#include "rmi/internal-encryption.h"
-#define INTERNAL_STORAGE_PATH "/opt/usr"
-#define INTERNAL_STORAGE_VCONF_KEY VCONFKEY_ODE_CRYPTO_STATE
+#define INTERNAL_ENGINE DMCryptEngine
+#define INTERNAL_DEV "/dev/mmcblk0p25"
+#define INTERNAL_PATH "/opt/usr"
+#define INTERNAL_STATE_VCONF_KEY VCONFKEY_ODE_CRYPTO_STATE
+#define INTERNAL_OPTION_ONLY_USED_REGION_VCONF_KEY VCONFKEY_ODE_FAST_ENCRYPTION
+
+#define PRIVILEGE_PLATFORM "http://tizen.org/privilege/internal/default/platform"
+
+const std::string PROG_FACTORY_RESET = "/usr/bin/dbus-send";
+const std::vector<std::string> wipeCommand = {
+ PROG_FACTORY_RESET,
+ "--system",
+ "--type=signal",
+ "--print-reply",
+ "--dest=com.samsung.factoryreset",
+ "/com/samsung/factoryreset",
+ "com.samsung.factoryreset.start.setting"
+};
namespace ode {
namespace {
-DMCryptEngine engine("/dev/mmcblk0p25", INTERNAL_STORAGE_PATH);
+std::unique_ptr<INTERNAL_ENGINE> engine;
void stopDependedSystemdServices()
{
dbus::Connection& systemDBus = dbus::Connection::getSystem();
std::set<std::string> servicesToStop;
- for (pid_t pid : runtime::FileUser::getList(INTERNAL_STORAGE_PATH, true)) {
+ for (pid_t pid : runtime::FileUser::getList(INTERNAL_PATH, true)) {
try {
char *service;
systemDBus.methodcall("org.freedesktop.systemd1",
}
void showProgressUI(const std::string type) {
+ ::tzplatform_set_user(::tzplatform_getuid(TZ_SYS_DEFAULT_USER));
+ std::string defaultUserHome(::tzplatform_getenv(TZ_USER_HOME));
+ ::tzplatform_reset_user();
+
+ ::tzplatform_set_user(::getuid());
+ std::string currentUserHome(::tzplatform_getenv(TZ_USER_HOME));
+ ::tzplatform_reset_user();
+
+ INFO("Home directory : " + currentUserHome);
+
+ runtime::File shareDirectory(currentUserHome + "/share");
+ if (!shareDirectory.exists()) {
+ shareDirectory.makeDirectory();
+ }
+
+ runtime::File elmConfigDir(currentUserHome + "/share/.elementary");
+ if (!elmConfigDir.exists()) {
+ runtime::File defaultElmConfigDir(defaultUserHome + "/share/.elementary");
+ defaultElmConfigDir.copyTo(shareDirectory.getPath());
+ }
+
std::vector<std::string> args = {
- "ode-gui", "progress", type, "Internal storage encryption"
+ "ode", "progress", type, "Internal"
};
- runtime::Process proc("/usr/bin/ode-gui", args);
+ runtime::Process proc("/usr/bin/ode", args);
proc.execute();
}
+unsigned int getOptions()
+{
+ unsigned int result = 0;
+ int value;
+
+ value = 0;
+ ::vconf_get_bool(INTERNAL_OPTION_ONLY_USED_REGION_VCONF_KEY, &value);
+ if (value) {
+ result |= InternalEncryption::Option::IncludeUnusedRegion;
+ }
+
+ return result;
+}
+
+void setOptions(unsigned int options)
+{
+ bool value;
+
+ if (options & InternalEncryption::Option::IncludeUnusedRegion) {
+ value = true;
+ } else {
+ value = false;
+ }
+ ::vconf_set_bool(INTERNAL_OPTION_ONLY_USED_REGION_VCONF_KEY, value);
+}
+
}
InternalEncryption::InternalEncryption(ODEControlContext& ctx) :
context(ctx)
{
- context.registerParametricMethod(this, "", (int)(InternalEncryption::mount)(std::string));
- context.registerNonparametricMethod(this, "", (int)(InternalEncryption::umount));
- context.registerParametricMethod(this, "", (int)(InternalEncryption::encrypt)(std::string));
- context.registerParametricMethod(this, "", (int)(InternalEncryption::decrypt)(std::string));
- context.registerParametricMethod(this, "", (int)(InternalEncryption::changePassword)(std::string, std::string));
- context.registerNonparametricMethod(this, "", (int)(InternalEncryption::getState));
+ context.expose(this, PRIVILEGE_PLATFORM, (int)(InternalEncryption::mount)(std::string));
+ context.expose(this, PRIVILEGE_PLATFORM, (int)(InternalEncryption::umount)());
+ context.expose(this, PRIVILEGE_PLATFORM, (int)(InternalEncryption::encrypt)(std::string, unsigned int));
+ context.expose(this, PRIVILEGE_PLATFORM, (int)(InternalEncryption::decrypt)(std::string));
+ context.expose(this, "", (int)(InternalEncryption::isPasswordInitialized)());
+ context.expose(this, PRIVILEGE_PLATFORM, (int)(InternalEncryption::initPassword)(std::string));
+ context.expose(this, PRIVILEGE_PLATFORM, (int)(InternalEncryption::cleanPassword)(std::string));
+ context.expose(this, PRIVILEGE_PLATFORM, (int)(InternalEncryption::changePassword)(std::string, std::string));
+ context.expose(this, PRIVILEGE_PLATFORM, (int)(InternalEncryption::verifyPassword)(std::string));
+ context.expose(this, "", (int)(InternalEncryption::getState)());
+ context.expose(this, "", (unsigned int)(InternalEncryption::getSupportedOptions)());
+
+ engine.reset(new INTERNAL_ENGINE(
+ INTERNAL_DEV, INTERNAL_PATH,
+ ProgressBar([](int v) {
+ ::vconf_set_str(VCONFKEY_ODE_ENCRYPT_PROGRESS,
+ std::to_string(v).c_str());
+ })
+ ));
}
InternalEncryption::~InternalEncryption()
}
KeyManager::data pwData(password.begin(), password.end());
- KeyManager keyManager(engine.getKeyMeta());
+ KeyManager keyManager(engine->getKeyMeta());
if (!keyManager.verifyPassword(pwData)) {
return -2;
}
- engine.mount(keyManager.getMasterKey(pwData));
+ engine->mount(keyManager.getMasterKey(pwData), getOptions());
return 0;
}
INFO("Close all processes using internal storage...");
stopDependedSystemdServices();
INFO("Umount internal storage...");
- engine.umount();
+ engine->umount();
return 0;
}
-int InternalEncryption::encrypt(const std::string& password)
+int InternalEncryption::encrypt(const std::string& password, unsigned int options)
{
if (getState() != State::Unencrypted) {
return -1;
}
KeyManager::data pwData(password.begin(), password.end());
- KeyManager keyManager;
+ KeyManager keyManager(engine->getKeyMeta());
- keyManager.initPassword(pwData);
- engine.setKeyMeta(keyManager.serialize());
+ if (!keyManager.verifyPassword(pwData)) {
+ return -2;
+ }
KeyManager::data MasterKey = keyManager.getMasterKey(pwData);
- auto encryptWorker = [MasterKey, this]() {
- showProgressUI("Encrypting");
-
- INFO("Close all processes using internal storage...");
- stopDependedSystemdServices();
- INFO("Umount internal storage...");
- while (::umount(INTERNAL_STORAGE_PATH) == -1) {
- if (errno != EBUSY) {
- break;
+ auto encryptWorker = [MasterKey, options, this]() {
+ try {
+ showProgressUI("Encrypting");
+
+ INFO("Close all processes using internal storage...");
+ stopDependedSystemdServices();
+ INFO("Umount internal storage...");
+ while (::umount(INTERNAL_PATH) == -1) {
+ if (errno != EBUSY) {
+ throw runtime::Exception("Umount error - " + std::to_string(errno));
+ }
+ stopDependedSystemdServices();
}
- }
- INFO("Encryption started...");
- ::vconf_set_str(INTERNAL_STORAGE_VCONF_KEY, "error_partially_encrypted");
- engine.encrypt(MasterKey);
- INFO("Sync disk...");
- sync();
- INFO("Encryption completed");
+ INFO("Encryption started...");
+ engine->encrypt(MasterKey, options);
+ setOptions(options & getSupportedOptions());
+ INFO("Sync disk...");
+ sync();
+ INFO("Encryption completed");
- ::vconf_set_str(INTERNAL_STORAGE_VCONF_KEY, "encrypted");
- ::reboot(RB_AUTOBOOT);
+ ::vconf_set_str(INTERNAL_STATE_VCONF_KEY, "encrypted");
+ ::reboot(RB_AUTOBOOT);
+ } catch (runtime::Exception &e) {
+ ::vconf_set_str(INTERNAL_STATE_VCONF_KEY, "error_partially_encrypted");
+ ERROR("Encryption failed - " + std::string(e.what()));
+ }
};
std::thread asyncWork(encryptWorker);
}
KeyManager::data pwData(password.begin(), password.end());
- KeyManager keyManager(engine.getKeyMeta());
+ KeyManager keyManager(engine->getKeyMeta());
if (!keyManager.verifyPassword(pwData)) {
return -2;
KeyManager::data MasterKey = keyManager.getMasterKey(pwData);
auto decryptWorker = [MasterKey, this]() {
- showProgressUI("Decrypting");
-
- INFO("Close all processes using internal storage...");
- stopDependedSystemdServices();
- INFO("Umount internal storage...");
try {
- engine.umount();
- } catch (runtime::Exception& e) {}
-
- INFO("Decryption started...");
- ::vconf_set_str(INTERNAL_STORAGE_VCONF_KEY, "error_partially_encrypted");
- engine.decrypt(MasterKey);
- INFO("Sync disk...");
- sync();
- INFO("Decryption completed");
-
- ::vconf_set_str(INTERNAL_STORAGE_VCONF_KEY, "unencrypted");
- ::reboot(RB_AUTOBOOT);
+ showProgressUI("Decrypting");
+
+ INFO("Close all processes using internal storage...");
+ stopDependedSystemdServices();
+ INFO("Umount internal storage...");
+ while (1) {
+ try {
+ engine->umount();
+ break;
+ } catch (runtime::Exception& e) {
+ stopDependedSystemdServices();
+ }
+ }
+
+ INFO("Decryption started...");
+ engine->decrypt(MasterKey, getOptions());
+ INFO("Sync disk...");
+ sync();
+ INFO("Decryption completed");
+
+ ::vconf_set_str(INTERNAL_STATE_VCONF_KEY, "unencrypted");
+ ::reboot(RB_AUTOBOOT);
+ } catch (runtime::Exception &e) {
+ ::vconf_set_str(INTERNAL_STATE_VCONF_KEY, "error_partially_encrypted");
+ ERROR("Decryption failed - " + std::string(e.what()));
+ }
};
std::thread asyncWork(decryptWorker);
return 0;
}
+int InternalEncryption::recovery()
+{
+ if (getState() != State::Unencrypted) {
+ return -1;
+ }
+
+ //TODO
+ runtime::Process proc(PROG_FACTORY_RESET, wipeCommand);
+ if (proc.execute() == -1) {
+ ERROR("Failed to launch factory-reset");
+ return -2;
+ }
+
+ return 0;
+}
+
+int InternalEncryption::isPasswordInitialized()
+{
+ if (engine->isKeyMetaSet()) {
+ return 1;
+ }
+ return 0;
+}
+
+int InternalEncryption::initPassword(const std::string& password)
+{
+ KeyManager::data pwData(password.begin(), password.end());
+ KeyManager keyManager;
+
+ keyManager.initPassword(pwData);
+ engine->setKeyMeta(keyManager.serialize());
+ return 0;
+}
+
+int InternalEncryption::cleanPassword(const std::string& password)
+{
+ KeyManager::data pwData(password.begin(), password.end());
+ KeyManager keyManager(engine->getKeyMeta());
+
+ if (!keyManager.verifyPassword(pwData)) {
+ return -2;
+ }
+
+ engine->clearKeyMeta();
+ return 0;
+}
+
int InternalEncryption::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());
+ KeyManager keyManager(engine->getKeyMeta());
if (!keyManager.verifyPassword(oldPwData)) {
return -2;
}
keyManager.changePassword(oldPwData, newPwData);
- engine.setKeyMeta(keyManager.serialize());
+ engine->setKeyMeta(keyManager.serialize());
return 0;
}
+int InternalEncryption::verifyPassword(const std::string& password)
+{
+ KeyManager::data pwData(password.begin(), password.end());
+ KeyManager keyManager(engine->getKeyMeta());
+
+ if (keyManager.verifyPassword(pwData)) {
+ return 1;
+ }
+ return 0;
+}
+
int InternalEncryption::getState()
{
- char *value = ::vconf_get_str(INTERNAL_STORAGE_VCONF_KEY);
+ char *value = ::vconf_get_str(INTERNAL_STATE_VCONF_KEY);
if (value == NULL) {
throw runtime::Exception("Failed to get vconf value");
}
return 0;
}
+unsigned int InternalEncryption::getSupportedOptions()
+{
+ return engine->getSupportedOptions();
+}
+
} // namespace ode