blob: e96733986e46288060791d3bbfc6ec57868d3930 [file] [log] [blame]
bigbiff7ba75002020-04-11 20:47:09 -04001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
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
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16
17#include "FsCrypt.h"
18
mauronofrio matarrese79820322020-05-25 19:48:56 +020019#include "Keymaster.h"
bigbiff7ba75002020-04-11 20:47:09 -040020#include "KeyStorage.h"
21#include "KeyUtil.h"
22#include "Utils.h"
23// #include "VoldUtil.h"
24
25#include <algorithm>
26#include <map>
27#include <set>
28#include <sstream>
29#include <string>
30#include <vector>
31
32#include <dirent.h>
33#include <errno.h>
34#include <fcntl.h>
35#include <limits.h>
36#include <selinux/android.h>
37#include <sys/mount.h>
38#include <sys/stat.h>
39#include <sys/types.h>
40#include <unistd.h>
41
42#include <private/android_filesystem_config.h>
43
44// #include "android/os/IVold.h"
45
46#include "cryptfs.h"
47
48#define EMULATED_USES_SELINUX 0
49#define MANAGE_MISC_DIRS 0
50
51#include <cutils/fs.h>
52#include <cutils/properties.h>
53
54#include <fscrypt/fscrypt.h>
55#include <fs_mgr.h>
56#include <keyutils.h>
57
58#include <android-base/file.h>
59#include <android-base/logging.h>
60#include <android-base/properties.h>
61#include <android-base/stringprintf.h>
62#include <android-base/unique_fd.h>
63
64
65using android::base::StringPrintf;
66using android::fs_mgr::GetEntryForMountPoint;
67using android::vold::kEmptyAuthentication;
68using android::vold::KeyBuffer;
mauronofrio matarrese79820322020-05-25 19:48:56 +020069using android::vold::Keymaster;
70using android::hardware::keymaster::V4_0::KeyFormat;
bigbiff7ba75002020-04-11 20:47:09 -040071// using android::vold::writeStringToFile;
72
73// Store main DE raw ref / policy
74std::string de_raw_ref;
75std::map<userid_t, std::string> s_de_key_raw_refs;
76std::map<userid_t, std::string> s_ce_key_raw_refs;
77
78namespace {
79
80struct PolicyKeyRef {
81 std::string contents_mode;
82 std::string filenames_mode;
83 std::string key_raw_ref;
84};
85
86const std::string device_key_dir = std::string() + DATA_MNT_POINT + fscrypt_unencrypted_folder;
87const std::string device_key_path = device_key_dir + "/key";
88const std::string device_key_temp = device_key_dir + "/temp";
89
90const std::string user_key_dir = std::string() + DATA_MNT_POINT + "/misc/vold/user_keys";
91const std::string user_key_temp = user_key_dir + "/temp";
92const std::string prepare_subdirs_path = "/sbin/vold_prepare_subdirs";
93
94const std::string systemwide_volume_key_dir =
95 std::string() + DATA_MNT_POINT + "/misc/vold/volume_keys";
96const int STORAGE_FLAG_DE = 1;
97const int STORAGE_FLAG_CE = 2;
98
99bool s_systemwide_keys_initialized = false;
100
101android::fs_mgr::Fstab fstab_default;
102
103// Some users are ephemeral, don't try to wipe their keys from disk
104std::set<userid_t> s_ephemeral_users;
105
106// TODO abolish this map, per b/26948053
107std::map<userid_t, KeyBuffer> s_ce_keys;
108
109} // namespace
110
111static bool fscrypt_is_emulated() {
112 return property_get_bool("persist.sys.emulate_fbe", false);
113}
114
115static const char* escape_empty(const std::string& value) {
116 return value.empty() ? "null" : value.c_str();
117}
118
119static std::string get_de_key_path(userid_t user_id) {
120 return StringPrintf("%s/de/%d", user_key_dir.c_str(), user_id);
121}
122
123static std::string get_ce_key_directory_path(userid_t user_id) {
124 return StringPrintf("%s/ce/%d", user_key_dir.c_str(), user_id);
125}
126
127// Returns the keys newest first
128static std::vector<std::string> get_ce_key_paths(const std::string& directory_path) {
129 auto dirp = std::unique_ptr<DIR, int (*)(DIR*)>(opendir(directory_path.c_str()), closedir);
130 if (!dirp) {
131 PLOG(ERROR) << "Unable to open ce key directory: " + directory_path;
132 return std::vector<std::string>();
133 }
134 std::vector<std::string> result;
135 for (;;) {
136 errno = 0;
137 auto const entry = readdir(dirp.get());
138 if (!entry) {
139 if (errno) {
140 PLOG(ERROR) << "Unable to read ce key directory: " + directory_path;
141 return std::vector<std::string>();
142 }
143 break;
144 }
145 if (entry->d_type != DT_DIR || entry->d_name[0] != 'c') {
146 LOG(DEBUG) << "Skipping non-key " << entry->d_name;
147 continue;
148 }
149 result.emplace_back(directory_path + "/" + entry->d_name);
150 }
151 std::sort(result.begin(), result.end());
152 std::reverse(result.begin(), result.end());
153 return result;
154}
155
156static std::string get_ce_key_current_path(const std::string& directory_path) {
157 return directory_path + "/current";
158}
159
160static bool get_ce_key_new_path(const std::string& directory_path,
161 const std::vector<std::string>& paths, std::string* ce_key_path) {
162 if (paths.empty()) {
163 *ce_key_path = get_ce_key_current_path(directory_path);
164 return true;
165 }
166 for (unsigned int i = 0; i < UINT_MAX; i++) {
167 auto const candidate = StringPrintf("%s/cx%010u", directory_path.c_str(), i);
168 if (paths[0] < candidate) {
169 *ce_key_path = candidate;
170 return true;
171 }
172 }
173 return false;
174}
175
176// Discard all keys but the named one; rename it to canonical name.
177// No point in acting on errors in this; ignore them.
178static void fixate_user_ce_key(const std::string& directory_path, const std::string& to_fix,
179 const std::vector<std::string>& paths) {
180 for (auto const other_path : paths) {
181 if (other_path != to_fix) {
182 android::vold::destroyKey(other_path);
183 }
184 }
185 auto const current_path = get_ce_key_current_path(directory_path);
186 if (to_fix != current_path) {
187 LOG(DEBUG) << "Renaming " << to_fix << " to " << current_path;
188 if (rename(to_fix.c_str(), current_path.c_str()) != 0) {
189 PLOG(WARNING) << "Unable to rename " << to_fix << " to " << current_path;
190 return;
191 }
192 }
193 android::vold::FsyncDirectory(directory_path);
194}
195
196static bool read_and_fixate_user_ce_key(userid_t user_id,
197 const android::vold::KeyAuthentication& auth,
198 KeyBuffer* ce_key) {
199 auto const directory_path = get_ce_key_directory_path(user_id);
200 auto const paths = get_ce_key_paths(directory_path);
201 for (auto const ce_key_path : paths) {
202 LOG(DEBUG) << "Trying user CE key " << ce_key_path;
203 if (android::vold::retrieveKey(ce_key_path, auth, ce_key)) {
204 LOG(DEBUG) << "Successfully retrieved key";
205 fixate_user_ce_key(directory_path, ce_key_path, paths);
206 return true;
207 }
208 }
209 LOG(ERROR) << "Failed to find working ce key for user " << user_id;
210 return false;
211}
212
mauronofrio matarrese79820322020-05-25 19:48:56 +0200213static bool is_wrapped_key_supported_common(const std::string& mount_point) {
mauronofrio matarrese17fb1212020-05-25 19:59:17 +0200214 LOG(DEBUG) << "Determining wrapped-key support for " << mount_point;
215 std::string wrapped_key_supported = android::base::GetProperty("fbe.data.wrappedkey", "false");
216 LOG(DEBUG) << "fbe.data.wrappedkey = " << wrapped_key_supported;
217 if (mount_point == DATA_MNT_POINT && wrapped_key_supported == "true") {
218 LOG(DEBUG) << "Wrapped key supported on " << mount_point;
219 return true;
220 } else {
mauronofrio matarrese79820322020-05-25 19:48:56 +0200221 return false;
222 }
mauronofrio matarrese79820322020-05-25 19:48:56 +0200223}
224
225bool is_wrapped_key_supported() {
226 return is_wrapped_key_supported_common(DATA_MNT_POINT);
227}
228
229bool is_wrapped_key_supported_external() {
230 return false;
231}
232
mauronofrio matarresef1079ed2020-05-25 20:52:57 +0200233bool is_metadata_wrapped_key_supported() {
234 LOG(DEBUG) << "Determining metadata wrapped-key support for " << mount_point;
235 std::string wrapped_key_supported = android::base::GetProperty("fbe.metadata.wrappedkey", "false");
236 LOG(DEBUG) << "fbe.metadata.wrappedkey = " << wrapped_key_supported;
237 if (mount_point == METADATA_MNT_POINT && wrapped_key_supported == "true") {
238 LOG(DEBUG) << "Wrapped key supported on " << mount_point;
239 return true;
240 } else {
241 return false;
242 }
243}
244
bigbiff7ba75002020-04-11 20:47:09 -0400245static bool read_and_install_user_ce_key(userid_t user_id,
246 const android::vold::KeyAuthentication& auth) {
247 if (s_ce_key_raw_refs.count(user_id) != 0) return true;
248 KeyBuffer ce_key;
249 if (!read_and_fixate_user_ce_key(user_id, auth, &ce_key)) return false;
250 std::string ce_raw_ref;
mauronofrio matarrese79820322020-05-25 19:48:56 +0200251 if (is_wrapped_key_supported()) {
252 KeyBuffer ephemeral_wrapped_key;
253 if (!getEphemeralWrappedKey(KeyFormat::RAW, ce_key, &ephemeral_wrapped_key)) {
254 LOG(ERROR) << "Failed to export ce key";
255 return false;
256 }
257 ce_key = std::move(ephemeral_wrapped_key);
258 }
bigbiff7ba75002020-04-11 20:47:09 -0400259 if (!android::vold::installKey(ce_key, &ce_raw_ref)) return false;
260 s_ce_keys[user_id] = std::move(ce_key);
261 s_ce_key_raw_refs[user_id] = ce_raw_ref;
262 LOG(DEBUG) << "Installed ce key for user " << user_id;
263 return true;
264}
265
266static bool prepare_dir(const std::string& dir, mode_t mode, uid_t uid, gid_t gid) {
267 LOG(DEBUG) << "Preparing: " << dir;
268 if (fs_prepare_dir(dir.c_str(), mode, uid, gid) != 0) {
269 PLOG(ERROR) << "Failed to prepare " << dir;
270 return false;
271 }
272 return true;
273}
274
275static bool destroy_dir(const std::string& dir) {
276 LOG(DEBUG) << "Destroying: " << dir;
277 if (rmdir(dir.c_str()) != 0 && errno != ENOENT) {
278 PLOG(ERROR) << "Failed to destroy " << dir;
279 return false;
280 }
281 return true;
282}
283
284// NB this assumes that there is only one thread listening for crypt commands, because
285// it creates keys in a fixed location.
286static bool create_and_install_user_keys(userid_t user_id, bool create_ephemeral) {
287 KeyBuffer de_key, ce_key;
mauronofrio matarrese79820322020-05-25 19:48:56 +0200288
289 if(is_wrapped_key_supported()) {
290 if (!generateWrappedKey(user_id, android::vold::KeyType::DE_USER, &de_key)) return false;
291 if (!generateWrappedKey(user_id, android::vold::KeyType::CE_USER, &ce_key)) return false;
292 } else {
293 if (!android::vold::randomKey(&de_key)) return false;
294 if (!android::vold::randomKey(&ce_key)) return false;
295 }
296
bigbiff7ba75002020-04-11 20:47:09 -0400297 if (create_ephemeral) {
298 // If the key should be created as ephemeral, don't store it.
299 s_ephemeral_users.insert(user_id);
300 } else {
301 auto const directory_path = get_ce_key_directory_path(user_id);
302 if (!prepare_dir(directory_path, 0700, AID_ROOT, AID_ROOT)) return false;
303 auto const paths = get_ce_key_paths(directory_path);
304 std::string ce_key_path;
305 if (!get_ce_key_new_path(directory_path, paths, &ce_key_path)) return false;
306 if (!android::vold::storeKeyAtomically(ce_key_path, user_key_temp, kEmptyAuthentication,
307 ce_key))
308 return false;
309 fixate_user_ce_key(directory_path, ce_key_path, paths);
310 // Write DE key second; once this is written, all is good.
311 if (!android::vold::storeKeyAtomically(get_de_key_path(user_id), user_key_temp,
312 kEmptyAuthentication, de_key))
313 return false;
314 }
mauronofrio matarrese79820322020-05-25 19:48:56 +0200315
bigbiff7ba75002020-04-11 20:47:09 -0400316 std::string ce_raw_ref;
mauronofrio matarrese79820322020-05-25 19:48:56 +0200317 if (is_wrapped_key_supported()) {
318 KeyBuffer ephemeral_wrapped_de_key;
319 KeyBuffer ephemeral_wrapped_ce_key;
320
321 /* Export and install the DE keys */
322 if (!getEphemeralWrappedKey(KeyFormat::RAW, de_key, &ephemeral_wrapped_de_key)) {
323 LOG(ERROR) << "Failed to export de_key";
324 return false;
325 }
326 /* Export and install the CE keys */
327 if (!getEphemeralWrappedKey(KeyFormat::RAW, ce_key, &ephemeral_wrapped_ce_key)) {
328 LOG(ERROR) << "Failed to export de_key";
329 return false;
330 }
331
332 de_key = std::move(ephemeral_wrapped_de_key);
333 ce_key = std::move(ephemeral_wrapped_ce_key);
334 }
335 if (!android::vold::installKey(de_key, &de_raw_ref)) return false;
bigbiff7ba75002020-04-11 20:47:09 -0400336 if (!android::vold::installKey(ce_key, &ce_raw_ref)) return false;
mauronofrio matarrese79820322020-05-25 19:48:56 +0200337 s_ce_keys[user_id] = std::move(ce_key);
338
339 s_de_key_raw_refs[user_id] = de_raw_ref;
bigbiff7ba75002020-04-11 20:47:09 -0400340 s_ce_key_raw_refs[user_id] = ce_raw_ref;
mauronofrio matarrese79820322020-05-25 19:48:56 +0200341
bigbiff7ba75002020-04-11 20:47:09 -0400342 LOG(DEBUG) << "Created keys for user " << user_id;
343 return true;
344}
345
346bool lookup_key_ref(const std::map<userid_t, std::string>& key_map, userid_t user_id,
347 std::string* raw_ref) {
348 auto refi = key_map.find(user_id);
349 if (refi == key_map.end()) {
350 LOG(DEBUG) << "Cannot find key for " << user_id;
351 return false;
352 }
353 *raw_ref = refi->second;
354 return true;
355}
356
357static void get_data_file_encryption_modes(PolicyKeyRef* key_ref) {
358 if (!ReadDefaultFstab(&fstab_default)) {
359 PLOG(ERROR) << "Failed to open default fstab";
360 return;
361 }
362 auto entry = android::fs_mgr::GetEntryForMountPoint(&fstab_default, DATA_MNT_POINT);
363 if (entry == nullptr) {
364 LOG(ERROR) << "get_data_file_encryption_modes::failed\n";
365 return;
366 }
367 key_ref->contents_mode = entry->file_contents_mode;
368 key_ref->filenames_mode = entry->file_names_mode;
369}
370
371static bool ensure_policy(const PolicyKeyRef& key_ref, const std::string& path) {
372 return fscrypt_policy_ensure(path.c_str(), key_ref.key_raw_ref.data(),
373 key_ref.key_raw_ref.size(), key_ref.contents_mode.c_str(),
374 key_ref.filenames_mode.c_str()) == 0;
375}
376
377static bool is_numeric(const char* name) {
378 for (const char* p = name; *p != '\0'; p++) {
379 if (!isdigit(*p)) return false;
380 }
381 return true;
382}
383
384static bool load_all_de_keys() {
385 auto de_dir = user_key_dir + "/de";
386 auto dirp = std::unique_ptr<DIR, int (*)(DIR*)>(opendir(de_dir.c_str()), closedir);
387 if (!dirp) {
388 PLOG(ERROR) << "Unable to read de key directory";
389 return false;
390 }
391 for (;;) {
392 errno = 0;
393 auto entry = readdir(dirp.get());
394 if (!entry) {
395 if (errno) {
396 PLOG(ERROR) << "Unable to read de key directory";
397 return false;
398 }
399 break;
400 }
401 if (entry->d_type != DT_DIR || !is_numeric(entry->d_name)) {
402 LOG(DEBUG) << "Skipping non-de-key " << entry->d_name;
403 continue;
404 }
405 userid_t user_id = std::stoi(entry->d_name);
406 if (s_de_key_raw_refs.count(user_id) == 0) {
407 auto key_path = de_dir + "/" + entry->d_name;
408 KeyBuffer key;
409 if (!android::vold::retrieveKey(key_path, kEmptyAuthentication, &key)) return false;
410 std::string raw_ref;
mauronofrio matarrese79820322020-05-25 19:48:56 +0200411 if (is_wrapped_key_supported()) {
412 KeyBuffer ephemeral_wrapped_key;
413 if (!getEphemeralWrappedKey(KeyFormat::RAW, key, &ephemeral_wrapped_key)) {
414 LOG(ERROR) << "Failed to export de_key in create_and_install_user_keys";
415 return false;
416 }
417 key = std::move(ephemeral_wrapped_key);
418 }
bigbiff7ba75002020-04-11 20:47:09 -0400419 if (!android::vold::installKey(key, &raw_ref)) return false;
420 s_de_key_raw_refs[user_id] = raw_ref;
421 LOG(DEBUG) << "Installed de key for user " << user_id;
422 }
423 }
424 // fscrypt:TODO: go through all DE directories, ensure that all user dirs have the
425 // correct policy set on them, and that no rogue ones exist.
426 return true;
427}
428
429bool fscrypt_initialize_systemwide_keys() {
430 LOG(INFO) << "fscrypt_initialize_systemwide_keys";
mauronofrio matarrese79820322020-05-25 19:48:56 +0200431 bool wrapped_key_supported = false;
bigbiff7ba75002020-04-11 20:47:09 -0400432
433 if (s_systemwide_keys_initialized) {
434 LOG(INFO) << "Already initialized";
435 return true;
436 }
437
438 PolicyKeyRef device_ref;
mauronofrio matarrese79820322020-05-25 19:48:56 +0200439 wrapped_key_supported = is_wrapped_key_supported();
440
441 if (!android::vold::retrieveAndInstallKey(true, kEmptyAuthentication,
442 device_key_path, device_key_temp,
443 &device_ref.key_raw_ref, wrapped_key_supported))
bigbiff7ba75002020-04-11 20:47:09 -0400444 return false;
445 get_data_file_encryption_modes(&device_ref);
446
447 std::string modestring = device_ref.contents_mode + ":" + device_ref.filenames_mode;
448 std::string mode_filename = std::string("/data") + fscrypt_key_mode;
449 if (!android::vold::writeStringToFile(modestring, mode_filename)) return false;
450
451 std::string ref_filename = std::string("/data") + fscrypt_key_ref;
452 if (!android::vold::writeStringToFile(device_ref.key_raw_ref, ref_filename)) return false;
453 LOG(INFO) << "Wrote system DE key reference to:" << ref_filename;
454
455 KeyBuffer per_boot_key;
456 if (!android::vold::randomKey(&per_boot_key)) return false;
457 std::string per_boot_raw_ref;
458 if (!android::vold::installKey(per_boot_key, &per_boot_raw_ref)) return false;
459 std::string per_boot_ref_filename = std::string("/data") + fscrypt_key_per_boot_ref;
460 if (!android::vold::writeStringToFile(per_boot_raw_ref, per_boot_ref_filename)) return false;
461 LOG(INFO) << "Wrote per boot key reference to:" << per_boot_ref_filename;
462
463 if (!android::vold::FsyncDirectory(device_key_dir)) return false;
464 s_systemwide_keys_initialized = true;
465 de_raw_ref = device_ref.key_raw_ref;
466 return true;
467}
468
469bool fscrypt_init_user0() {
470 if (!ReadDefaultFstab(&fstab_default)) {
471 PLOG(ERROR) << "Failed to open default fstab";
472 return -1;
473 }
474 if (fscrypt_is_native()) {
475 if (!prepare_dir(user_key_dir, 0700, AID_ROOT, AID_ROOT)) return false;
476 if (!prepare_dir(user_key_dir + "/ce", 0700, AID_ROOT, AID_ROOT)) return false;
477 if (!prepare_dir(user_key_dir + "/de", 0700, AID_ROOT, AID_ROOT)) return false;
478 if (!android::vold::pathExists(get_de_key_path(0))) {
479 if (!create_and_install_user_keys(0, false)) return false;
480 }
481 // TODO: switch to loading only DE_0 here once framework makes
482 // explicit calls to install DE keys for secondary users
483 if (!load_all_de_keys()) return false;
484 }
485 // We can only safely prepare DE storage here, since CE keys are probably
486 // entangled with user credentials. The framework will always prepare CE
487 // storage once CE keys are installed.
488 if (!fscrypt_prepare_user_storage("", 0, 0, STORAGE_FLAG_DE)) {
489 LOG(ERROR) << "Failed to prepare user 0 storage";
490 return false;
491 }
492 // If this is a non-FBE device that recently left an emulated mode,
493 // restore user data directories to known-good state.
494 if (!fscrypt_is_native() && !fscrypt_is_emulated()) {
495 fscrypt_unlock_user_key(0, 0, "!", "!");
496 }
497
498 return true;
499}
500
501bool fscrypt_vold_create_user_key(userid_t user_id, int serial, bool ephemeral) {
502 LOG(DEBUG) << "fscrypt_vold_create_user_key for " << user_id << " serial " << serial;
503 if (!fscrypt_is_native()) {
504 return true;
505 }
506 // FIXME test for existence of key that is not loaded yet
507 if (s_ce_key_raw_refs.count(user_id) != 0) {
508 LOG(ERROR) << "Already exists, can't fscrypt_vold_create_user_key for " << user_id
509 << " serial " << serial;
510 // FIXME should we fail the command?
511 return true;
512 }
513 if (!create_and_install_user_keys(user_id, ephemeral)) {
514 return false;
515 }
516 return true;
517}
518
519static void drop_caches() {
520 // Clean any dirty pages (otherwise they won't be dropped).
521 sync();
522 // Drop inode and page caches.
523 if (!android::vold::writeStringToFile("3", "/proc/sys/vm/drop_caches")) {
524 PLOG(ERROR) << "Failed to drop caches during key eviction";
525 }
526}
527
528static bool evict_ce_key(userid_t user_id) {
529 s_ce_keys.erase(user_id);
530 bool success = true;
531 std::string raw_ref;
532 // If we haven't loaded the CE key, no need to evict it.
533 if (lookup_key_ref(s_ce_key_raw_refs, user_id, &raw_ref)) {
534 success &= android::vold::evictKey(raw_ref);
535 drop_caches();
536 }
537 s_ce_key_raw_refs.erase(user_id);
538 return success;
539}
540
541bool fscrypt_destroy_user_key(userid_t user_id) {
542 LOG(DEBUG) << "fscrypt_destroy_user_key(" << user_id << ")";
543 if (!fscrypt_is_native()) {
544 return true;
545 }
546 bool success = true;
547 std::string raw_ref;
548 success &= evict_ce_key(user_id);
549 success &=
550 lookup_key_ref(s_de_key_raw_refs, user_id, &raw_ref) && android::vold::evictKey(raw_ref);
551 s_de_key_raw_refs.erase(user_id);
552 auto it = s_ephemeral_users.find(user_id);
553 if (it != s_ephemeral_users.end()) {
554 s_ephemeral_users.erase(it);
555 } else {
556 for (auto const path : get_ce_key_paths(get_ce_key_directory_path(user_id))) {
557 success &= android::vold::destroyKey(path);
558 }
559 auto de_key_path = get_de_key_path(user_id);
560 if (android::vold::pathExists(de_key_path)) {
561 success &= android::vold::destroyKey(de_key_path);
562 } else {
563 LOG(INFO) << "Not present so not erasing: " << de_key_path;
564 }
565 }
566 return success;
567}
568
569static bool emulated_lock(const std::string& path) {
570 if (chmod(path.c_str(), 0000) != 0) {
571 PLOG(ERROR) << "Failed to chmod " << path;
572 return false;
573 }
574#if EMULATED_USES_SELINUX
575 if (setfilecon(path.c_str(), "u:object_r:storage_stub_file:s0") != 0) {
576 PLOG(WARNING) << "Failed to setfilecon " << path;
577 return false;
578 }
579#endif
580 return true;
581}
582
583static bool emulated_unlock(const std::string& path, mode_t mode) {
584 if (chmod(path.c_str(), mode) != 0) {
585 PLOG(ERROR) << "Failed to chmod " << path;
586 // FIXME temporary workaround for b/26713622
587 if (fscrypt_is_emulated()) return false;
588 }
589#if EMULATED_USES_SELINUX
590 if (selinux_android_restorecon(path.c_str(), SELINUX_ANDROID_RESTORECON_FORCE) != 0) {
591 PLOG(WARNING) << "Failed to restorecon " << path;
592 // FIXME temporary workaround for b/26713622
593 if (fscrypt_is_emulated()) return false;
594 }
595#endif
596 return true;
597}
598
599static bool parse_hex(const std::string& hex, std::string* result) {
600 if (hex == "!") {
601 *result = "";
602 return true;
603 }
604 if (android::vold::HexToStr(hex, *result) != 0) {
605 LOG(ERROR) << "Invalid FBE hex string"; // Don't log the string for security reasons
606 return false;
607 }
608 return true;
609}
610
611static std::string volkey_path(const std::string& misc_path, const std::string& volume_uuid) {
612 return misc_path + "/vold/volume_keys/" + volume_uuid + "/default";
613}
614
615static std::string volume_secdiscardable_path(const std::string& volume_uuid) {
616 return systemwide_volume_key_dir + "/" + volume_uuid + "/secdiscardable";
617}
618
619static bool read_or_create_volkey(const std::string& misc_path, const std::string& volume_uuid,
620 PolicyKeyRef* key_ref) {
621 auto secdiscardable_path = volume_secdiscardable_path(volume_uuid);
622 std::string secdiscardable_hash;
mauronofrio matarrese79820322020-05-25 19:48:56 +0200623 bool wrapped_key_supported = false;
bigbiff7ba75002020-04-11 20:47:09 -0400624 if (android::vold::pathExists(secdiscardable_path)) {
625 if (!android::vold::readSecdiscardable(secdiscardable_path, &secdiscardable_hash))
626 return false;
627 } else {
628 if (fs_mkdirs(secdiscardable_path.c_str(), 0700) != 0) {
629 PLOG(ERROR) << "Creating directories for: " << secdiscardable_path;
630 return false;
631 }
632 if (!android::vold::createSecdiscardable(secdiscardable_path, &secdiscardable_hash))
633 return false;
634 }
635 auto key_path = volkey_path(misc_path, volume_uuid);
636 if (fs_mkdirs(key_path.c_str(), 0700) != 0) {
637 PLOG(ERROR) << "Creating directories for: " << key_path;
638 return false;
639 }
640 android::vold::KeyAuthentication auth("", secdiscardable_hash);
mauronofrio matarrese79820322020-05-25 19:48:56 +0200641 wrapped_key_supported = is_wrapped_key_supported_external();
642
bigbiff7ba75002020-04-11 20:47:09 -0400643 if (!android::vold::retrieveAndInstallKey(true, auth, key_path, key_path + "_tmp",
mauronofrio matarrese79820322020-05-25 19:48:56 +0200644 &key_ref->key_raw_ref, wrapped_key_supported))
bigbiff7ba75002020-04-11 20:47:09 -0400645 return false;
646 key_ref->contents_mode =
647 android::base::GetProperty("ro.crypto.volume.contents_mode", "aes-256-xts");
648 key_ref->filenames_mode =
649 android::base::GetProperty("ro.crypto.volume.filenames_mode", "aes-256-heh");
650 return true;
651}
652
653static bool destroy_volkey(const std::string& misc_path, const std::string& volume_uuid) {
654 auto path = volkey_path(misc_path, volume_uuid);
655 if (!android::vold::pathExists(path)) return true;
656 return android::vold::destroyKey(path);
657}
658
659bool fscrypt_add_user_key_auth(userid_t user_id, int serial, const std::string& token_hex,
660 const std::string& secret_hex) {
661 LOG(DEBUG) << "fscrypt_add_user_key_auth " << user_id << " serial=" << serial
662 << " token_present=" << (token_hex != "!");
663 if (!fscrypt_is_native()) return true;
664 if (s_ephemeral_users.count(user_id) != 0) return true;
665 std::string token, secret;
666 if (!parse_hex(token_hex, &token)) return false;
667 if (!parse_hex(secret_hex, &secret)) return false;
668 auto auth =
669 secret.empty() ? kEmptyAuthentication : android::vold::KeyAuthentication(token, secret);
bigbiff7ba75002020-04-11 20:47:09 -0400670 auto const directory_path = get_ce_key_directory_path(user_id);
671 auto const paths = get_ce_key_paths(directory_path);
mauronofrio matarrese79820322020-05-25 19:48:56 +0200672
673 KeyBuffer ce_key;
674 if(is_wrapped_key_supported()) {
675 std::string ce_key_current_path = get_ce_key_current_path(directory_path);
676 if (android::vold::retrieveKey(ce_key_current_path, kEmptyAuthentication, &ce_key)) {
677 LOG(DEBUG) << "Successfully retrieved key";
678 } else {
679 if (android::vold::retrieveKey(ce_key_current_path, auth, &ce_key)) {
680 LOG(DEBUG) << "Successfully retrieved key";
681 }
682 }
683 } else {
684 auto it = s_ce_keys.find(user_id);
685 if (it == s_ce_keys.end()) {
686 LOG(ERROR) << "Key not loaded into memory, can't change for user " << user_id;
687 return false;
688 }
689 ce_key = it->second;
690 }
691
bigbiff7ba75002020-04-11 20:47:09 -0400692 std::string ce_key_path;
693 if (!get_ce_key_new_path(directory_path, paths, &ce_key_path)) return false;
694 if (!android::vold::storeKeyAtomically(ce_key_path, user_key_temp, auth, ce_key)) return false;
695 if (!android::vold::FsyncDirectory(directory_path)) return false;
696 return true;
697}
698
mauronofrio matarrese79820322020-05-25 19:48:56 +0200699bool fscrypt_clear_user_key_auth(userid_t user_id, int serial, const std::string& token_hex,
700 const std::string& secret_hex) {
701 LOG(DEBUG) << "fscrypt_clear_user_key_auth " << user_id << " serial=" << serial
702 << " token_present=" << (token_hex != "!");
703 if (!fscrypt_is_native()) return true;
704 if (s_ephemeral_users.count(user_id) != 0) return true;
705 std::string token, secret;
706
707 if (!parse_hex(token_hex, &token)) return false;
708 if (!parse_hex(secret_hex, &secret)) return false;
709
710 if (is_wrapped_key_supported()) {
711 auto const directory_path = get_ce_key_directory_path(user_id);
712 auto const paths = get_ce_key_paths(directory_path);
713
714 KeyBuffer ce_key;
715 std::string ce_key_current_path = get_ce_key_current_path(directory_path);
716
717 auto auth = android::vold::KeyAuthentication(token, secret);
718 /* Retrieve key while removing a pin. A secret is needed */
719 if (android::vold::retrieveKey(ce_key_current_path, auth, &ce_key)) {
720 LOG(DEBUG) << "Successfully retrieved key";
721 } else {
722 /* Retrieve key when going None to swipe and vice versa when a
723 synthetic password is present */
724 if (android::vold::retrieveKey(ce_key_current_path, kEmptyAuthentication, &ce_key)) {
725 LOG(DEBUG) << "Successfully retrieved key";
726 }
727 }
728
729 std::string ce_key_path;
730 if (!get_ce_key_new_path(directory_path, paths, &ce_key_path)) return false;
731 if (!android::vold::storeKeyAtomically(ce_key_path, user_key_temp, kEmptyAuthentication, ce_key))
732 return false;
733 } else {
734 if(!fscrypt_add_user_key_auth(user_id, serial, "!", "!")) return false;
735 }
736 return true;
737}
738
bigbiff7ba75002020-04-11 20:47:09 -0400739bool fscrypt_fixate_newest_user_key_auth(userid_t user_id) {
740 LOG(DEBUG) << "fscrypt_fixate_newest_user_key_auth " << user_id;
741 if (!fscrypt_is_native()) return true;
742 if (s_ephemeral_users.count(user_id) != 0) return true;
743 auto const directory_path = get_ce_key_directory_path(user_id);
744 auto const paths = get_ce_key_paths(directory_path);
745 if (paths.empty()) {
746 LOG(ERROR) << "No ce keys present, cannot fixate for user " << user_id;
747 return false;
748 }
749 fixate_user_ce_key(directory_path, paths[0], paths);
750 return true;
751}
752
753// TODO: rename to 'install' for consistency, and take flags to know which keys to install
754bool fscrypt_unlock_user_key(userid_t user_id, int serial, const std::string& token_hex,
755 const std::string& secret_hex) {
756 LOG(DEBUG) << "fscrypt_unlock_user_key " << user_id << " serial=" << serial
757 << " token_present=" << (token_hex != "!");
758 if (fscrypt_is_native()) {
759 if (s_ce_key_raw_refs.count(user_id) != 0) {
760 LOG(WARNING) << "Tried to unlock already-unlocked key for user " << user_id;
761 return true;
762 }
763 std::string token, secret;
764 if (!parse_hex(token_hex, &token)) return false;
765 if (!parse_hex(secret_hex, &secret)) return false;
766 android::vold::KeyAuthentication auth(token, secret);
767 if (!read_and_install_user_ce_key(user_id, auth)) {
768 LOG(ERROR) << "Couldn't read key for " << user_id;
769 return false;
770 }
771 } else {
772 // When in emulation mode, we just use chmod. However, we also
773 // unlock directories when not in emulation mode, to bring devices
774 // back into a known-good state.
775 if (!emulated_unlock(android::vold::BuildDataSystemCePath(user_id), 0771) ||
776 !emulated_unlock(android::vold::BuildDataMiscCePath(user_id), 01771) ||
777 !emulated_unlock(android::vold::BuildDataMediaCePath("", user_id), 0770) ||
778 !emulated_unlock(android::vold::BuildDataUserCePath("", user_id), 0771)) {
779 LOG(ERROR) << "Failed to unlock user " << user_id;
780 return false;
781 }
782 }
783 return true;
784}
785
786// TODO: rename to 'evict' for consistency
787bool fscrypt_lock_user_key(userid_t user_id) {
788 LOG(DEBUG) << "fscrypt_lock_user_key " << user_id;
789 if (fscrypt_is_native()) {
790 return evict_ce_key(user_id);
791 } else if (fscrypt_is_emulated()) {
792 // When in emulation mode, we just use chmod
793 if (!emulated_lock(android::vold::BuildDataSystemCePath(user_id)) ||
794 !emulated_lock(android::vold::BuildDataMiscCePath(user_id)) ||
795 !emulated_lock(android::vold::BuildDataMediaCePath("", user_id)) ||
796 !emulated_lock(android::vold::BuildDataUserCePath("", user_id))) {
797 LOG(ERROR) << "Failed to lock user " << user_id;
798 return false;
799 }
800 }
801
802 return true;
803}
804
805static bool prepare_subdirs(const std::string& action, const std::string& volume_uuid,
806 userid_t user_id, int flags) {
807 if (0 != android::vold::ForkExecvp(
808 std::vector<std::string>{prepare_subdirs_path, action, volume_uuid,
809 std::to_string(user_id), std::to_string(flags)})) {
810 LOG(ERROR) << "vold_prepare_subdirs failed";
811 return false;
812 }
813 return true;
814}
815
816bool fscrypt_prepare_user_storage(const std::string& volume_uuid, userid_t user_id, int serial,
817 int flags) {
818 LOG(DEBUG) << "fscrypt_prepare_user_storage for volume " << escape_empty(volume_uuid)
819 << ", user " << user_id << ", serial " << serial << ", flags " << flags;
820
821 if (flags & STORAGE_FLAG_DE) {
822 // DE_sys key
823 auto system_legacy_path = android::vold::BuildDataSystemLegacyPath(user_id);
824 auto misc_legacy_path = android::vold::BuildDataMiscLegacyPath(user_id);
825 auto profiles_de_path = android::vold::BuildDataProfilesDePath(user_id);
826
827 // DE_n key
828 auto system_de_path = android::vold::BuildDataSystemDePath(user_id);
829 auto misc_de_path = android::vold::BuildDataMiscDePath(user_id);
830 auto vendor_de_path = android::vold::BuildDataVendorDePath(user_id);
831 auto user_de_path = android::vold::BuildDataUserDePath(volume_uuid, user_id);
832
833 if (volume_uuid.empty()) {
834 if (!prepare_dir(system_legacy_path, 0700, AID_SYSTEM, AID_SYSTEM)) return false;
835#if MANAGE_MISC_DIRS
836 if (!prepare_dir(misc_legacy_path, 0750, multiuser_get_uid(user_id, AID_SYSTEM),
837 multiuser_get_uid(user_id, AID_EVERYBODY)))
838 return false;
839#endif
840 if (!prepare_dir(profiles_de_path, 0771, AID_SYSTEM, AID_SYSTEM)) return false;
841
842 if (!prepare_dir(system_de_path, 0770, AID_SYSTEM, AID_SYSTEM)) return false;
843 if (!prepare_dir(misc_de_path, 01771, AID_SYSTEM, AID_MISC)) return false;
844 if (!prepare_dir(vendor_de_path, 0771, AID_ROOT, AID_ROOT)) return false;
845 }
846 if (!prepare_dir(user_de_path, 0771, AID_SYSTEM, AID_SYSTEM)) return false;
847
848 if (fscrypt_is_native()) {
849 PolicyKeyRef de_ref;
850 if (volume_uuid.empty()) {
851 if (!lookup_key_ref(s_de_key_raw_refs, user_id, &de_ref.key_raw_ref)) return false;
852 get_data_file_encryption_modes(&de_ref);
853 if (!ensure_policy(de_ref, system_de_path)) return false;
854 if (!ensure_policy(de_ref, misc_de_path)) return false;
855 if (!ensure_policy(de_ref, vendor_de_path)) return false;
856 } else {
857 if (!read_or_create_volkey(misc_de_path, volume_uuid, &de_ref)) return false;
858 }
859 if (!ensure_policy(de_ref, user_de_path)) return false;
860 }
861 }
862 if (flags & STORAGE_FLAG_CE) {
863 // CE_n key
864 auto system_ce_path = android::vold::BuildDataSystemCePath(user_id);
865 auto misc_ce_path = android::vold::BuildDataMiscCePath(user_id);
866 auto vendor_ce_path = android::vold::BuildDataVendorCePath(user_id);
867 auto media_ce_path = android::vold::BuildDataMediaCePath(volume_uuid, user_id);
868 auto user_ce_path = android::vold::BuildDataUserCePath(volume_uuid, user_id);
869
870 if (volume_uuid.empty()) {
871 if (!prepare_dir(system_ce_path, 0770, AID_SYSTEM, AID_SYSTEM)) return false;
872 if (!prepare_dir(misc_ce_path, 01771, AID_SYSTEM, AID_MISC)) return false;
873 if (!prepare_dir(vendor_ce_path, 0771, AID_ROOT, AID_ROOT)) return false;
874 }
875 if (!prepare_dir(media_ce_path, 0770, AID_MEDIA_RW, AID_MEDIA_RW)) return false;
876 if (!prepare_dir(user_ce_path, 0771, AID_SYSTEM, AID_SYSTEM)) return false;
877
878 if (fscrypt_is_native()) {
879 PolicyKeyRef ce_ref;
880 if (volume_uuid.empty()) {
881 if (!lookup_key_ref(s_ce_key_raw_refs, user_id, &ce_ref.key_raw_ref)) return false;
882 get_data_file_encryption_modes(&ce_ref);
883 if (!ensure_policy(ce_ref, system_ce_path)) return false;
884 if (!ensure_policy(ce_ref, misc_ce_path)) return false;
885 if (!ensure_policy(ce_ref, vendor_ce_path)) return false;
886
887 } else {
888 if (!read_or_create_volkey(misc_ce_path, volume_uuid, &ce_ref)) return false;
889 }
890 if (!ensure_policy(ce_ref, media_ce_path)) return false;
891 if (!ensure_policy(ce_ref, user_ce_path)) return false;
892 }
893
894 if (volume_uuid.empty()) {
895 // Now that credentials have been installed, we can run restorecon
896 // over these paths
897 // NOTE: these paths need to be kept in sync with libselinux
898 android::vold::RestoreconRecursive(system_ce_path);
899 android::vold::RestoreconRecursive(vendor_ce_path);
900 android::vold::RestoreconRecursive(misc_ce_path);
901 }
902 }
903 if (!prepare_subdirs("prepare", volume_uuid, user_id, flags)) return false;
904
905 return true;
906}
907
908bool fscrypt_destroy_user_storage(const std::string& volume_uuid, userid_t user_id, int flags) {
909 LOG(DEBUG) << "fscrypt_destroy_user_storage for volume " << escape_empty(volume_uuid)
910 << ", user " << user_id << ", flags " << flags;
911 bool res = true;
912
913 res &= prepare_subdirs("destroy", volume_uuid, user_id, flags);
914
915 if (flags & STORAGE_FLAG_CE) {
916 // CE_n key
917 auto system_ce_path = android::vold::BuildDataSystemCePath(user_id);
918 auto misc_ce_path = android::vold::BuildDataMiscCePath(user_id);
919 auto vendor_ce_path = android::vold::BuildDataVendorCePath(user_id);
920 auto media_ce_path = android::vold::BuildDataMediaCePath(volume_uuid, user_id);
921 auto user_ce_path = android::vold::BuildDataUserCePath(volume_uuid, user_id);
922
923 res &= destroy_dir(media_ce_path);
924 res &= destroy_dir(user_ce_path);
925 if (volume_uuid.empty()) {
926 res &= destroy_dir(system_ce_path);
927 res &= destroy_dir(misc_ce_path);
928 res &= destroy_dir(vendor_ce_path);
929 } else {
930 if (fscrypt_is_native()) {
931 res &= destroy_volkey(misc_ce_path, volume_uuid);
932 }
933 }
934 }
935
936 if (flags & STORAGE_FLAG_DE) {
937 // DE_sys key
938 auto system_legacy_path = android::vold::BuildDataSystemLegacyPath(user_id);
939 auto misc_legacy_path = android::vold::BuildDataMiscLegacyPath(user_id);
940 auto profiles_de_path = android::vold::BuildDataProfilesDePath(user_id);
941
942 // DE_n key
943 auto system_de_path = android::vold::BuildDataSystemDePath(user_id);
944 auto misc_de_path = android::vold::BuildDataMiscDePath(user_id);
945 auto vendor_de_path = android::vold::BuildDataVendorDePath(user_id);
946 auto user_de_path = android::vold::BuildDataUserDePath(volume_uuid, user_id);
947
948 res &= destroy_dir(user_de_path);
949 if (volume_uuid.empty()) {
950 res &= destroy_dir(system_legacy_path);
951#if MANAGE_MISC_DIRS
952 res &= destroy_dir(misc_legacy_path);
953#endif
954 res &= destroy_dir(profiles_de_path);
955 res &= destroy_dir(system_de_path);
956 res &= destroy_dir(misc_de_path);
957 res &= destroy_dir(vendor_de_path);
958 } else {
959 if (fscrypt_is_native()) {
960 res &= destroy_volkey(misc_de_path, volume_uuid);
961 }
962 }
963 }
964
965 return res;
966}
967
968static bool destroy_volume_keys(const std::string& directory_path, const std::string& volume_uuid) {
969 auto dirp = std::unique_ptr<DIR, int (*)(DIR*)>(opendir(directory_path.c_str()), closedir);
970 if (!dirp) {
971 PLOG(ERROR) << "Unable to open directory: " + directory_path;
972 return false;
973 }
974 bool res = true;
975 for (;;) {
976 errno = 0;
977 auto const entry = readdir(dirp.get());
978 if (!entry) {
979 if (errno) {
980 PLOG(ERROR) << "Unable to read directory: " + directory_path;
981 return false;
982 }
983 break;
984 }
985 if (entry->d_type != DT_DIR || entry->d_name[0] == '.') {
986 LOG(DEBUG) << "Skipping non-user " << entry->d_name;
987 continue;
988 }
989 res &= destroy_volkey(directory_path + "/" + entry->d_name, volume_uuid);
990 }
991 return res;
992}
993
994bool fscrypt_destroy_volume_keys(const std::string& volume_uuid) {
995 bool res = true;
996 LOG(DEBUG) << "fscrypt_destroy_volume_keys for volume " << escape_empty(volume_uuid);
997 auto secdiscardable_path = volume_secdiscardable_path(volume_uuid);
998 res &= android::vold::runSecdiscardSingle(secdiscardable_path);
999 res &= destroy_volume_keys("/data/misc_ce", volume_uuid);
1000 res &= destroy_volume_keys("/data/misc_de", volume_uuid);
1001 return res;
1002}