2 * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
21 #include <sys/mount.h>
22 #include <sys/reboot.h>
25 #include <tzplatform_config.h>
26 #include <klay/process.h>
27 #include <klay/file-user.h>
28 #include <klay/filesystem.h>
29 #include <klay/dbus/connection.h>
30 #include <klay/audit/logger.h>
33 #include "progress-bar.h"
34 #include "engine/encryption/dmcrypt-engine.h"
35 #include "key-manager/key-manager.h"
37 #include "rmi/internal-encryption.h"
39 #define INTERNAL_ENGINE DMCryptEngine
40 #define INTERNAL_DEV "/dev/mmcblk0p25"
41 #define INTERNAL_PATH "/opt/usr"
42 #define INTERNAL_STATE_VCONF_KEY VCONFKEY_ODE_CRYPTO_STATE
43 #define INTERNAL_OPTION_ONLY_USED_REGION_VCONF_KEY VCONFKEY_ODE_FAST_ENCRYPTION
45 #define PRIVILEGE_PLATFORM "http://tizen.org/privilege/internal/default/platform"
47 const std::string PROG_FACTORY_RESET = "/usr/bin/dbus-send";
48 const std::vector<std::string> wipeCommand = {
53 "--dest=com.samsung.factoryreset",
54 "/com/samsung/factoryreset",
55 "com.samsung.factoryreset.start.setting"
62 std::unique_ptr<INTERNAL_ENGINE> engine;
63 KeyManager::data mountKey;
65 void stopSystemdUserSessions() {
66 std::vector<std::string> userSessionServices;
67 dbus::Connection& systemDBus = dbus::Connection::getSystem();
68 dbus::VariantIterator iter;
70 systemDBus.methodcall("org.freedesktop.systemd1",
71 "/org/freedesktop/systemd1",
72 "org.freedesktop.systemd1.Manager",
74 -1, "(a(ssssssouso))", "")
75 .get("(a(ssssssouso))", &iter);
78 unsigned int dataUint;
82 ret = iter.get("(ssssssouso)", dataStr, dataStr + 1, dataStr + 2,
83 dataStr + 3, dataStr + 4, dataStr + 5,
84 dataStr + 6, &dataUint, dataStr + 7,
91 std::string service(dataStr[0]);
92 if (service.compare(0, 5, "user@") == 0) {
93 userSessionServices.push_back(service);
97 for (const std::string& service : userSessionServices) {
98 INFO("Stop service - " + service);
99 systemDBus.methodcall("org.freedesktop.systemd1",
100 "/org/freedesktop/systemd1",
101 "org.freedesktop.systemd1.Manager",
103 -1, "", "(ss)", service.c_str(), "flush");
109 void stopDependedSystemdServices()
111 dbus::Connection& systemDBus = dbus::Connection::getSystem();
112 std::set<std::string> servicesToStop;
114 for (pid_t pid : runtime::FileUser::getList(INTERNAL_PATH, true)) {
117 systemDBus.methodcall("org.freedesktop.systemd1",
118 "/org/freedesktop/systemd1",
119 "org.freedesktop.systemd1.Manager",
121 -1, "(o)", "(u)", (unsigned int)pid)
122 .get("(o)", &service);
123 servicesToStop.insert(service);
124 } catch (runtime::Exception &e) {
125 INFO("Close process - " + std::to_string(pid));
126 ::kill(pid, SIGKILL);
130 for (const std::string& service : servicesToStop) {
131 INFO("Close service - " + service);
132 systemDBus.methodcall("org.freedesktop.systemd1",
134 "org.freedesktop.systemd1.Unit",
136 -1, "", "(s)", "flush");
140 void showProgressUI(const std::string type) {
141 ::tzplatform_set_user(::tzplatform_getuid(TZ_SYS_DEFAULT_USER));
142 std::string defaultUserHome(::tzplatform_getenv(TZ_USER_HOME));
143 ::tzplatform_reset_user();
146 runtime::File shareDirectory("/opt/home/root/share");
147 if (!shareDirectory.exists()) {
148 shareDirectory.makeDirectory(true);
151 runtime::File elmConfigDir(shareDirectory.getPath() + "/.elementary");
152 if (!elmConfigDir.exists()) {
153 runtime::File defaultElmConfigDir(defaultUserHome + "/share/.elementary");
154 defaultElmConfigDir.copyTo(shareDirectory.getPath());
156 } catch (runtime::Exception &e) {
157 ERROR("Failed to set up elm configuration");
160 std::vector<std::string> args = {
161 "ode", "progress", type, "Internal"
164 runtime::Process proc("/usr/bin/ode", args);
168 unsigned int getOptions()
170 unsigned int result = 0;
174 ::vconf_get_bool(INTERNAL_OPTION_ONLY_USED_REGION_VCONF_KEY, &value);
176 result |= InternalEncryption::Option::IncludeUnusedRegion;
182 void setOptions(unsigned int options)
186 if (options & InternalEncryption::Option::IncludeUnusedRegion) {
191 ::vconf_set_bool(INTERNAL_OPTION_ONLY_USED_REGION_VCONF_KEY, value);
196 InternalEncryption::InternalEncryption(ODEControlContext& ctx) :
199 context.expose(this, PRIVILEGE_PLATFORM, (int)(InternalEncryption::setMountPassword)(std::string));
200 context.expose(this, PRIVILEGE_PLATFORM, (int)(InternalEncryption::mount)());
201 context.expose(this, PRIVILEGE_PLATFORM, (int)(InternalEncryption::umount)());
202 context.expose(this, PRIVILEGE_PLATFORM, (int)(InternalEncryption::encrypt)(std::string, unsigned int));
203 context.expose(this, PRIVILEGE_PLATFORM, (int)(InternalEncryption::decrypt)(std::string));
204 context.expose(this, "", (int)(InternalEncryption::isPasswordInitialized)());
205 context.expose(this, PRIVILEGE_PLATFORM, (int)(InternalEncryption::initPassword)(std::string));
206 context.expose(this, PRIVILEGE_PLATFORM, (int)(InternalEncryption::cleanPassword)(std::string));
207 context.expose(this, PRIVILEGE_PLATFORM, (int)(InternalEncryption::changePassword)(std::string, std::string));
208 context.expose(this, PRIVILEGE_PLATFORM, (int)(InternalEncryption::verifyPassword)(std::string));
209 context.expose(this, "", (int)(InternalEncryption::getState)());
210 context.expose(this, "", (unsigned int)(InternalEncryption::getSupportedOptions)());
212 context.createNotification("InternalEncryption::mount");
214 engine.reset(new INTERNAL_ENGINE(
215 INTERNAL_DEV, INTERNAL_PATH,
216 ProgressBar([](int v) {
217 ::vconf_set_str(VCONFKEY_ODE_ENCRYPT_PROGRESS,
218 std::to_string(v).c_str());
223 InternalEncryption::~InternalEncryption()
227 int InternalEncryption::setMountPassword(const std::string& password)
229 KeyManager::data pwData(password.begin(), password.end());
230 KeyManager keyManager(engine->getKeyMeta());
231 if (!keyManager.verifyPassword(pwData)) {
235 ode::mountKey = keyManager.getMasterKey(pwData);
240 int InternalEncryption::mount()
242 if (getState() != State::Encrypted) {
246 if (engine->isMounted()) {
247 INFO("Already mounted");
251 engine->mount(mountKey, getOptions());
254 context.notify("InternalEncryption::mount");
256 runtime::File("/tmp/.lazy_mount").create(O_WRONLY);
257 runtime::File("/tmp/.unlock_mnt").create(O_WRONLY);
262 int InternalEncryption::umount()
264 if (getState() != State::Encrypted) {
268 if (!engine->isMounted()) {
269 INFO("Already umounted");
273 INFO("Close all processes using internal storage...");
274 stopDependedSystemdServices();
275 INFO("Umount internal storage...");
281 int InternalEncryption::encrypt(const std::string& password, unsigned int options)
283 if (getState() != State::Unencrypted) {
287 KeyManager::data pwData(password.begin(), password.end());
288 KeyManager keyManager(engine->getKeyMeta());
290 if (!keyManager.verifyPassword(pwData)) {
294 KeyManager::data MasterKey = keyManager.getMasterKey(pwData);
295 auto encryptWorker = [MasterKey, options, this]() {
297 INFO("Close all user sessions...");
298 stopSystemdUserSessions();
299 INFO("Close all processes using internal storage...");
300 stopDependedSystemdServices();
301 INFO("Umount internal storage...");
302 while (::umount(INTERNAL_PATH) == -1) {
303 if (errno != EBUSY) {
304 throw runtime::Exception("Umount error - " + std::to_string(errno));
306 stopDependedSystemdServices();
309 showProgressUI("Encrypting");
311 INFO("Encryption started...");
312 engine->encrypt(MasterKey, options);
313 setOptions(options & getSupportedOptions());
314 INFO("Sync disk...");
316 INFO("Encryption completed");
318 ::vconf_set_str(INTERNAL_STATE_VCONF_KEY, "encrypted");
319 ::reboot(RB_AUTOBOOT);
320 } catch (runtime::Exception &e) {
321 ::vconf_set_str(INTERNAL_STATE_VCONF_KEY, "error_partially_encrypted");
322 ERROR("Encryption failed - " + std::string(e.what()));
326 std::thread asyncWork(encryptWorker);
332 int InternalEncryption::decrypt(const std::string& password)
334 if (getState() != State::Encrypted) {
338 KeyManager::data pwData(password.begin(), password.end());
339 KeyManager keyManager(engine->getKeyMeta());
341 if (!keyManager.verifyPassword(pwData)) {
345 KeyManager::data MasterKey = keyManager.getMasterKey(pwData);
346 auto decryptWorker = [MasterKey, this]() {
348 INFO("Close all user sessions...");
349 stopSystemdUserSessions();
350 INFO("Close all processes using internal storage...");
351 stopDependedSystemdServices();
352 INFO("Umount internal storage...");
357 } catch (runtime::Exception& e) {
358 stopDependedSystemdServices();
362 showProgressUI("Decrypting");
364 INFO("Decryption started...");
365 engine->decrypt(MasterKey, getOptions());
366 INFO("Sync disk...");
368 INFO("Decryption completed");
370 ::vconf_set_str(INTERNAL_STATE_VCONF_KEY, "unencrypted");
371 ::reboot(RB_AUTOBOOT);
372 } catch (runtime::Exception &e) {
373 ::vconf_set_str(INTERNAL_STATE_VCONF_KEY, "error_partially_encrypted");
374 ERROR("Decryption failed - " + std::string(e.what()));
378 std::thread asyncWork(decryptWorker);
384 int InternalEncryption::recovery()
386 if (getState() != State::Unencrypted) {
391 runtime::Process proc(PROG_FACTORY_RESET, wipeCommand);
392 if (proc.execute() == -1) {
393 ERROR("Failed to launch factory-reset");
400 int InternalEncryption::isPasswordInitialized()
402 if (engine->isKeyMetaSet()) {
408 int InternalEncryption::initPassword(const std::string& password)
410 KeyManager::data pwData(password.begin(), password.end());
411 KeyManager keyManager;
413 keyManager.initPassword(pwData);
414 engine->setKeyMeta(keyManager.serialize());
418 int InternalEncryption::cleanPassword(const std::string& password)
420 KeyManager::data pwData(password.begin(), password.end());
421 KeyManager keyManager(engine->getKeyMeta());
423 if (!keyManager.verifyPassword(pwData)) {
427 engine->clearKeyMeta();
431 int InternalEncryption::changePassword(const std::string& oldPassword,
432 const std::string& newPassword)
434 KeyManager::data oldPwData(oldPassword.begin(), oldPassword.end());
435 KeyManager::data newPwData(newPassword.begin(), newPassword.end());
436 KeyManager keyManager(engine->getKeyMeta());
438 if (!keyManager.verifyPassword(oldPwData)) {
442 keyManager.changePassword(oldPwData, newPwData);
443 engine->setKeyMeta(keyManager.serialize());
448 int InternalEncryption::verifyPassword(const std::string& password)
450 KeyManager::data pwData(password.begin(), password.end());
451 KeyManager keyManager(engine->getKeyMeta());
453 if (keyManager.verifyPassword(pwData)) {
459 int InternalEncryption::getState()
461 char *value = ::vconf_get_str(INTERNAL_STATE_VCONF_KEY);
463 throw runtime::Exception("Failed to get vconf value");
466 std::string valueStr(value);
469 if (valueStr == "encrypted") {
470 return State::Encrypted;
471 } else if (valueStr == "unencrypted") {
472 return State::Unencrypted;
474 return State::Corrupted;
480 unsigned int InternalEncryption::getSupportedOptions()
482 return engine->getSupportedOptions();