blob: 423147d66d4e26a8544c028e608d6d31466f96f6 [file] [log] [blame]
Ethan Yonkerbd7492d2016-12-07 13:55:01 -06001/*
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 "Ext4Crypt.h"
18#include "Decrypt.h"
19
20#include "KeyStorage.h"
21#include "Utils.h"
22
23#include <algorithm>
24#include <iomanip>
25#include <map>
26#include <set>
27#include <sstream>
28#include <string>
29
30#include <dirent.h>
31#include <errno.h>
32#include <fcntl.h>
33#include <limits.h>
34#include <openssl/sha.h>
35#include <selinux/android.h>
36#include <stdio.h>
37#include <sys/mount.h>
38#include <sys/stat.h>
39#include <sys/types.h>
40#include <iostream>
41
42#include <private/android_filesystem_config.h>
43
44#include "ext4_crypt.h"
45#include "key_control.h"
46
47#include <hardware/gatekeeper.h>
48#include "HashPassword.h"
49
50#define EMULATED_USES_SELINUX 0
51#define MANAGE_MISC_DIRS 0
52
53#include <cutils/fs.h>
54
55#include <android-base/file.h>
56//#include <android-base/logging.h>
57#include <android-base/stringprintf.h>
58
59#define LOG(x) std::cout
60#define PLOG(x) std::cout
61#define DATA_MNT_POINT "/data"
62
63using android::base::StringPrintf;
64using android::vold::kEmptyAuthentication;
65
66// NOTE: keep in sync with StorageManager
67//static constexpr int FLAG_STORAGE_DE = 1 << 0; // moved to Decrypt.h
68//static constexpr int FLAG_STORAGE_CE = 1 << 1;
69
70namespace {
71const std::string device_key_dir = std::string() + DATA_MNT_POINT + e4crypt_unencrypted_folder;
72const std::string device_key_path = device_key_dir + "/key";
73const std::string device_key_temp = device_key_dir + "/temp";
74
75const std::string user_key_dir = std::string() + DATA_MNT_POINT + "/misc/vold/user_keys";
76const std::string user_key_temp = user_key_dir + "/temp";
77
78bool s_global_de_initialized = false;
79
80// Some users are ephemeral, don't try to wipe their keys from disk
81std::set<userid_t> s_ephemeral_users;
82
83// Map user ids to key references
84std::map<userid_t, std::string> s_de_key_raw_refs;
85std::map<userid_t, std::string> s_ce_key_raw_refs;
86// TODO abolish this map. Keys should not be long-lived in user memory, only kernel memory.
87// See b/26948053
88std::map<userid_t, std::string> s_ce_keys;
89
90// ext4enc:TODO get this const from somewhere good
91const int EXT4_KEY_DESCRIPTOR_SIZE = 8;
92
93// ext4enc:TODO Include structure from somewhere sensible
94// MUST be in sync with ext4_crypto.c in kernel
95constexpr int EXT4_ENCRYPTION_MODE_AES_256_XTS = 1;
96constexpr int EXT4_AES_256_XTS_KEY_SIZE = 64;
97constexpr int EXT4_MAX_KEY_SIZE = 64;
98struct ext4_encryption_key {
99 uint32_t mode;
100 char raw[EXT4_MAX_KEY_SIZE];
101 uint32_t size;
102};
103}
104
105static bool e4crypt_is_emulated() {
106 return false; //property_get_bool("persist.sys.emulate_fbe", false);
107}
108
109static const char* escape_null(const char* value) {
110 return (value == nullptr) ? "null" : value;
111}
112
113// Get raw keyref - used to make keyname and to pass to ioctl
114static std::string generate_key_ref(const char* key, int length) {
115 SHA512_CTX c;
116
117 SHA512_Init(&c);
118 SHA512_Update(&c, key, length);
119 unsigned char key_ref1[SHA512_DIGEST_LENGTH];
120 SHA512_Final(key_ref1, &c);
121
122 SHA512_Init(&c);
123 SHA512_Update(&c, key_ref1, SHA512_DIGEST_LENGTH);
124 unsigned char key_ref2[SHA512_DIGEST_LENGTH];
125 SHA512_Final(key_ref2, &c);
126
127 static_assert(EXT4_KEY_DESCRIPTOR_SIZE <= SHA512_DIGEST_LENGTH,
128 "Hash too short for descriptor");
129 return std::string((char*)key_ref2, EXT4_KEY_DESCRIPTOR_SIZE);
130}
131
132static bool fill_key(const std::string& key, ext4_encryption_key* ext4_key) {
133 if (key.size() != EXT4_AES_256_XTS_KEY_SIZE) {
134 LOG(ERROR) << "Wrong size key " << key.size();
135 return false;
136 }
137 static_assert(EXT4_AES_256_XTS_KEY_SIZE <= sizeof(ext4_key->raw), "Key too long!");
138 ext4_key->mode = EXT4_ENCRYPTION_MODE_AES_256_XTS;
139 ext4_key->size = key.size();
140 memset(ext4_key->raw, 0, sizeof(ext4_key->raw));
141 memcpy(ext4_key->raw, key.data(), key.size());
142 return true;
143}
144
145static std::string keyname(const std::string& raw_ref) {
146 std::ostringstream o;
147 o << "ext4:";
148 for (auto i : raw_ref) {
149 o << std::hex << std::setw(2) << std::setfill('0') << (int)i;
150 }
151 LOG(INFO) << "keyname is " << o.str() << "\n";
152 return o.str();
153}
154
155// Get the keyring we store all keys in
156static bool e4crypt_keyring(key_serial_t* device_keyring) {
157 *device_keyring = keyctl_search(KEY_SPEC_SESSION_KEYRING, "keyring", "e4crypt", 0);
158 if (*device_keyring == -1) {
159 PLOG(ERROR) << "Unable to find device keyring\n";
160 return false;
161 }
162 return true;
163}
164
165// Install password into global keyring
166// Return raw key reference for use in policy
167static bool install_key(const std::string& key, std::string* raw_ref) {
168 ext4_encryption_key ext4_key;
169 if (!fill_key(key, &ext4_key)) return false;
170 *raw_ref = generate_key_ref(ext4_key.raw, ext4_key.size);
171 auto ref = keyname(*raw_ref);
172 key_serial_t device_keyring;
173 if (!e4crypt_keyring(&device_keyring)) return false;
174 key_serial_t key_id =
175 add_key("logon", ref.c_str(), (void*)&ext4_key, sizeof(ext4_key), device_keyring);
176 if (key_id == -1) {
177 PLOG(ERROR) << "Failed to insert key into keyring " << device_keyring << "\n";
178 return false;
179 }
180 LOG(DEBUG) << "Added key " << key_id << " (" << ref << ") to keyring " << device_keyring
181 << " in process " << getpid() << "\n";
182 return true;
183}
184
185static std::string get_de_key_path(userid_t user_id) {
186LOG(INFO) << "get_de_key_path " << user_id << " " << StringPrintf("%s/de/%d", user_key_dir.c_str(), user_id) << "\n";
187 return StringPrintf("%s/de/%d", user_key_dir.c_str(), user_id);
188}
189
190static std::string get_ce_key_directory_path(userid_t user_id) {
191LOG(INFO) << "get_ce_key_directory_path " << user_id << ": " << StringPrintf("%s/ce/%d", user_key_dir.c_str(), user_id) << "\n";
192 return StringPrintf("%s/ce/%d", user_key_dir.c_str(), user_id);
193}
194
195// Returns the keys newest first
196static std::vector<std::string> get_ce_key_paths(const std::string& directory_path) {
197 auto dirp = std::unique_ptr<DIR, int (*)(DIR*)>(opendir(directory_path.c_str()), closedir);
198 if (!dirp) {
199 PLOG(ERROR) << "Unable to open ce key directory: " + directory_path;
200 return std::vector<std::string>();
201 }
202 std::vector<std::string> result;
203 for (;;) {
204 errno = 0;
205 auto const entry = readdir(dirp.get());
206 if (!entry) {
207 if (errno) {
208 PLOG(ERROR) << "Unable to read ce key directory: " + directory_path;
209 return std::vector<std::string>();
210 }
211 break;
212 }
213 if (entry->d_type != DT_DIR || entry->d_name[0] != 'c') {
214 LOG(DEBUG) << "Skipping non-key " << entry->d_name;
215 continue;
216 }
217 result.emplace_back(directory_path + "/" + entry->d_name);
218 LOG(INFO) << "get_ce_key_paths adding: " << directory_path + "/" + entry->d_name << "\n";
219 }
220 std::sort(result.begin(), result.end());
221 std::reverse(result.begin(), result.end());
222 return result;
223}
224
225static std::string get_ce_key_current_path(const std::string& directory_path) {
226LOG(INFO) << "get_ce_key_current_path: " << directory_path + "/current\n";
227 return directory_path + "/current";
228}
229
230// Discard all keys but the named one; rename it to canonical name.
231// No point in acting on errors in this; ignore them.
232static void fixate_user_ce_key(const std::string& directory_path, const std::string &to_fix,
233 const std::vector<std::string>& paths) {
234 for (auto const other_path: paths) {
235 if (other_path != to_fix) {
236 android::vold::destroyKey(other_path);
237 }
238 }
239 auto const current_path = get_ce_key_current_path(directory_path);
240 if (to_fix != current_path) {
241 LOG(DEBUG) << "Renaming " << to_fix << " to " << current_path;
242 if (rename(to_fix.c_str(), current_path.c_str()) != 0) {
243 PLOG(WARNING) << "Unable to rename " << to_fix << " to " << current_path;
244 }
245 }
246}
247
248static bool read_and_fixate_user_ce_key(userid_t user_id,
249 const android::vold::KeyAuthentication& auth,
250 std::string *ce_key) {
251 auto const directory_path = get_ce_key_directory_path(user_id);
252 auto const paths = get_ce_key_paths(directory_path);
253 for (auto const ce_key_path: paths) {
254 LOG(DEBUG) << "Trying user CE key " << ce_key_path;
255 if (android::vold::retrieveKey(ce_key_path, auth, ce_key)) {
256 LOG(DEBUG) << "Successfully retrieved key";
257 fixate_user_ce_key(directory_path, ce_key_path, paths);
258 return true;
259 }
260 }
261 LOG(ERROR) << "Failed to find working ce key for user " << user_id;
262 return false;
263}
264
265static bool read_and_install_user_ce_key(userid_t user_id,
266 const android::vold::KeyAuthentication& auth) {
267 if (s_ce_key_raw_refs.count(user_id) != 0) return true;
268 std::string ce_key;
269 if (!read_and_fixate_user_ce_key(user_id, auth, &ce_key)) return false;
270 std::string ce_raw_ref;
271 if (!install_key(ce_key, &ce_raw_ref)) return false;
272 s_ce_keys[user_id] = ce_key;
273 s_ce_key_raw_refs[user_id] = ce_raw_ref;
274 LOG(DEBUG) << "Installed ce key for user " << user_id;
275 return true;
276}
277
278static bool prepare_dir(const std::string& dir, mode_t mode, uid_t uid, gid_t gid) {
279 LOG(DEBUG) << "Preparing: " << dir << "\n";
280 return true;
281 return access(dir.c_str(), F_OK) == 0; // we don't want recovery creating directories or changing permissions at this point, so we will just return true if the path already exists
282 if (fs_prepare_dir(dir.c_str(), mode, uid, gid) != 0) {
283 PLOG(ERROR) << "Failed to prepare " << dir;
284 return false;
285 }
286 return true;
287}
288
289static bool path_exists(const std::string& path) {
290 return access(path.c_str(), F_OK) == 0;
291}
292
293static bool lookup_key_ref(const std::map<userid_t, std::string>& key_map, userid_t user_id,
294 std::string* raw_ref) {
295 auto refi = key_map.find(user_id);
296 if (refi == key_map.end()) {
297 LOG(ERROR) << "Cannot find key for " << user_id;
298 return false;
299 }
300 *raw_ref = refi->second;
301 return true;
302}
303
304static bool ensure_policy(const std::string& raw_ref, const std::string& path) {
305 LOG(INFO) << "ensure_policy '" << path << "'\n";
306 return true;
307 return access(path.c_str(), F_OK) == 0; // ensure policy will set a policy if one is not set on an empty folder - we don't want to do this in recovery
308 /*if (e4crypt_policy_ensure(path.c_str(), raw_ref.data(), raw_ref.size()) != 0) {
309 LOG(ERROR) << "Failed to set policy on: " << path << "\n";
310 return false;
311 }
312 return true;*/
313}
314
315static bool is_numeric(const char* name) {
316 for (const char* p = name; *p != '\0'; p++) {
317 if (!isdigit(*p)) return false;
318 }
319 return true;
320}
321
322static bool load_all_de_keys() {
323 auto de_dir = user_key_dir + "/de";
324 auto dirp = std::unique_ptr<DIR, int (*)(DIR*)>(opendir(de_dir.c_str()), closedir);
325 if (!dirp) {
326 PLOG(ERROR) << "Unable to read de key directory";
327 return false;
328 }
329 for (;;) {
330 errno = 0;
331 auto entry = readdir(dirp.get());
332 if (!entry) {
333 if (errno) {
334 PLOG(ERROR) << "Unable to read de key directory";
335 return false;
336 }
337 break;
338 }
339 if (entry->d_type != DT_DIR || !is_numeric(entry->d_name)) {
340 LOG(DEBUG) << "Skipping non-de-key " << entry->d_name;
341 continue;
342 }
343 userid_t user_id = atoi(entry->d_name);
344 if (s_de_key_raw_refs.count(user_id) == 0) {
345 auto key_path = de_dir + "/" + entry->d_name;
346 std::string key;
347 if (!android::vold::retrieveKey(key_path, kEmptyAuthentication, &key)) return false;
348 std::string raw_ref;
349 if (!install_key(key, &raw_ref)) return false;
350 s_de_key_raw_refs[user_id] = raw_ref;
351 LOG(DEBUG) << "Installed de key for user " << user_id;
352 }
353 }
354 // ext4enc:TODO: go through all DE directories, ensure that all user dirs have the
355 // correct policy set on them, and that no rogue ones exist.
356 return true;
357}
358
359bool e4crypt_initialize_global_de() {
360
361 if (s_global_de_initialized) {
362 LOG(INFO) << "Already initialized\n";
363 return true;
364 }
365
366 std::string device_key;
367 if (path_exists(device_key_path)) {
368 if (!android::vold::retrieveKey(device_key_path,
369 kEmptyAuthentication, &device_key)) return false;
370 } else {
371 LOG(INFO) << "NOT Creating new key\n";
372 return false;
373 }
374
375 std::string device_key_ref;
376 if (!install_key(device_key, &device_key_ref)) {
377 LOG(ERROR) << "Failed to install device key\n";
378 return false;
379 }
380
381 s_global_de_initialized = true;
382 return true;
383}
384
385bool e4crypt_init_user0() {
386 if (e4crypt_is_native()) {
387 if (!prepare_dir(user_key_dir, 0700, AID_ROOT, AID_ROOT)) return false;
388 if (!prepare_dir(user_key_dir + "/ce", 0700, AID_ROOT, AID_ROOT)) return false;
389 if (!prepare_dir(user_key_dir + "/de", 0700, AID_ROOT, AID_ROOT)) return false;
390 if (!path_exists(get_de_key_path(0))) {
391 //if (!create_and_install_user_keys(0, false)) return false;
392 printf("de key path not found\n");
393 return false;
394 }
395 // TODO: switch to loading only DE_0 here once framework makes
396 // explicit calls to install DE keys for secondary users
397 if (!load_all_de_keys()) return false;
398 }
399 // We can only safely prepare DE storage here, since CE keys are probably
400 // entangled with user credentials. The framework will always prepare CE
401 // storage once CE keys are installed.
402 if (!e4crypt_prepare_user_storage(nullptr, 0, 0, FLAG_STORAGE_DE)) {
403 LOG(ERROR) << "Failed to prepare user 0 storage";
404 return false;
405 }
406
407 // If this is a non-FBE device that recently left an emulated mode,
408 // restore user data directories to known-good state.
409 if (!e4crypt_is_native() && !e4crypt_is_emulated()) {
410 e4crypt_unlock_user_key(0, 0, "!", "!");
411 }
412
413 return true;
414}
415
416static bool parse_hex(const char* hex, std::string* result) {
417 if (strcmp("!", hex) == 0) {
418 *result = "";
419 return true;
420 }
421 if (android::vold::HexToStr(hex, *result) != 0) {
422 LOG(ERROR) << "Invalid FBE hex string"; // Don't log the string for security reasons
423 return false;
424 }
425 return true;
426}
427
428// TODO: rename to 'install' for consistency, and take flags to know which keys to install
429bool e4crypt_unlock_user_key(userid_t user_id, int serial, const char* token_hex,
430 const char* secret_hex) {
431 if (e4crypt_is_native()) {
432 if (s_ce_key_raw_refs.count(user_id) != 0) {
433 LOG(WARNING) << "Tried to unlock already-unlocked key for user " << user_id;
434 return true;
435 }
436 std::string token, secret;
437 if (!parse_hex(token_hex, &token)) return false;
438 if (!parse_hex(secret_hex, &secret)) return false;
439 android::vold::KeyAuthentication auth(token, secret);
440 if (!read_and_install_user_ce_key(user_id, auth)) {
441 LOG(ERROR) << "Couldn't read key for " << user_id;
442 return false;
443 }
444 } else {
445 printf("Emulation mode not supported in TWRP\n");
446 // When in emulation mode, we just use chmod. However, we also
447 // unlock directories when not in emulation mode, to bring devices
448 // back into a known-good state.
449 /*if (!emulated_unlock(android::vold::BuildDataSystemCePath(user_id), 0771) ||
450 !emulated_unlock(android::vold::BuildDataMiscCePath(user_id), 01771) ||
451 !emulated_unlock(android::vold::BuildDataMediaCePath(nullptr, user_id), 0770) ||
452 !emulated_unlock(android::vold::BuildDataUserCePath(nullptr, user_id), 0771)) {
453 LOG(ERROR) << "Failed to unlock user " << user_id;
454 return false;
455 }*/
456 }
457 return true;
458}
459
460bool e4crypt_prepare_user_storage(const char* volume_uuid, userid_t user_id, int serial,
461 int flags) {
462
463 if (flags & FLAG_STORAGE_DE) {
464 // DE_sys key
465 auto system_legacy_path = android::vold::BuildDataSystemLegacyPath(user_id);
466 auto misc_legacy_path = android::vold::BuildDataMiscLegacyPath(user_id);
467 auto profiles_de_path = android::vold::BuildDataProfilesDePath(user_id);
468 auto foreign_de_path = android::vold::BuildDataProfilesForeignDexDePath(user_id);
469
470 // DE_n key
471 auto system_de_path = android::vold::BuildDataSystemDePath(user_id);
472 auto misc_de_path = android::vold::BuildDataMiscDePath(user_id);
473 auto user_de_path = android::vold::BuildDataUserDePath(volume_uuid, user_id);
474
475 if (!prepare_dir(system_legacy_path, 0700, AID_SYSTEM, AID_SYSTEM)) return false;
476#if MANAGE_MISC_DIRS
477 if (!prepare_dir(misc_legacy_path, 0750, multiuser_get_uid(user_id, AID_SYSTEM),
478 multiuser_get_uid(user_id, AID_EVERYBODY))) return false;
479#endif
480 if (!prepare_dir(profiles_de_path, 0771, AID_SYSTEM, AID_SYSTEM)) return false;
481 if (!prepare_dir(foreign_de_path, 0773, AID_SYSTEM, AID_SYSTEM)) return false;
482
483 if (!prepare_dir(system_de_path, 0770, AID_SYSTEM, AID_SYSTEM)) return false;
484 if (!prepare_dir(misc_de_path, 01771, AID_SYSTEM, AID_MISC)) return false;
485 if (!prepare_dir(user_de_path, 0771, AID_SYSTEM, AID_SYSTEM)) return false;
486
487 // For now, FBE is only supported on internal storage
488 if (e4crypt_is_native() && volume_uuid == nullptr) {
489 std::string de_raw_ref;
490 if (!lookup_key_ref(s_de_key_raw_refs, user_id, &de_raw_ref)) return false;
491 if (!ensure_policy(de_raw_ref, system_de_path)) return false;
492 if (!ensure_policy(de_raw_ref, misc_de_path)) return false;
493 if (!ensure_policy(de_raw_ref, user_de_path)) return false;
494 }
495 }
496
497 if (flags & FLAG_STORAGE_CE) {
498 // CE_n key
499 auto system_ce_path = android::vold::BuildDataSystemCePath(user_id);
500 auto misc_ce_path = android::vold::BuildDataMiscCePath(user_id);
501 auto media_ce_path = android::vold::BuildDataMediaCePath(volume_uuid, user_id);
502 auto user_ce_path = android::vold::BuildDataUserCePath(volume_uuid, user_id);
503
504 if (!prepare_dir(system_ce_path, 0770, AID_SYSTEM, AID_SYSTEM)) return false;
505 if (!prepare_dir(misc_ce_path, 01771, AID_SYSTEM, AID_MISC)) return false;
506 if (!prepare_dir(media_ce_path, 0770, AID_MEDIA_RW, AID_MEDIA_RW)) return false;
507 if (!prepare_dir(user_ce_path, 0771, AID_SYSTEM, AID_SYSTEM)) return false;
508
509 // For now, FBE is only supported on internal storage
510 if (e4crypt_is_native() && volume_uuid == nullptr) {
511 std::string ce_raw_ref;
512 if (!lookup_key_ref(s_ce_key_raw_refs, user_id, &ce_raw_ref)) return false;
513 if (!ensure_policy(ce_raw_ref, system_ce_path)) return false;
514 if (!ensure_policy(ce_raw_ref, misc_ce_path)) return false;
515 if (!ensure_policy(ce_raw_ref, media_ce_path)) return false;
516 if (!ensure_policy(ce_raw_ref, user_ce_path)) return false;
517 }
518 }
519
520 return true;
521}