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