|
|
|
@ -77,6 +77,7 @@ extern "C" {
|
|
|
|
|
|
|
|
|
|
using android::base::ParseUint;
|
|
|
|
|
using android::base::StringPrintf;
|
|
|
|
|
using android::fs_mgr::GetEntryForMountPoint;
|
|
|
|
|
using namespace std::chrono_literals;
|
|
|
|
|
|
|
|
|
|
#define UNUSED __attribute__((unused))
|
|
|
|
@ -404,7 +405,7 @@ const char* cryptfs_get_crypto_name() {
|
|
|
|
|
return get_crypto_type().get_crypto_name();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static uint64_t get_fs_size(char* dev) {
|
|
|
|
|
static uint64_t get_fs_size(const char* dev) {
|
|
|
|
|
int fd, block_size;
|
|
|
|
|
struct ext4_super_block sb;
|
|
|
|
|
uint64_t len;
|
|
|
|
@ -438,6 +439,22 @@ static uint64_t get_fs_size(char* dev) {
|
|
|
|
|
return len / 512;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void get_crypt_info(std::string* key_loc, std::string* real_blk_device) {
|
|
|
|
|
for (const auto& entry : fstab_default) {
|
|
|
|
|
if (!entry.fs_mgr_flags.vold_managed &&
|
|
|
|
|
(entry.fs_mgr_flags.crypt || entry.fs_mgr_flags.force_crypt ||
|
|
|
|
|
entry.fs_mgr_flags.force_fde_or_fbe || entry.fs_mgr_flags.file_encryption)) {
|
|
|
|
|
if (key_loc != nullptr) {
|
|
|
|
|
*key_loc = entry.key_loc;
|
|
|
|
|
}
|
|
|
|
|
if (real_blk_device != nullptr) {
|
|
|
|
|
*real_blk_device = entry.blk_device;
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int get_crypt_ftr_info(char** metadata_fname, off64_t* off) {
|
|
|
|
|
static int cached_data = 0;
|
|
|
|
|
static uint64_t cached_off = 0;
|
|
|
|
@ -447,22 +464,24 @@ static int get_crypt_ftr_info(char** metadata_fname, off64_t* off) {
|
|
|
|
|
int rc = -1;
|
|
|
|
|
|
|
|
|
|
if (!cached_data) {
|
|
|
|
|
fs_mgr_get_crypt_info(fstab_default, key_loc, real_blkdev, sizeof(key_loc));
|
|
|
|
|
std::string key_loc;
|
|
|
|
|
std::string real_blkdev;
|
|
|
|
|
get_crypt_info(&key_loc, &real_blkdev);
|
|
|
|
|
|
|
|
|
|
if (!strcmp(key_loc, KEY_IN_FOOTER)) {
|
|
|
|
|
if (key_loc == KEY_IN_FOOTER) {
|
|
|
|
|
if (android::vold::GetBlockDevSize(real_blkdev, &cached_off) == android::OK) {
|
|
|
|
|
/* If it's an encrypted Android partition, the last 16 Kbytes contain the
|
|
|
|
|
* encryption info footer and key, and plenty of bytes to spare for future
|
|
|
|
|
* growth.
|
|
|
|
|
*/
|
|
|
|
|
strlcpy(cached_metadata_fname, real_blkdev, sizeof(cached_metadata_fname));
|
|
|
|
|
strlcpy(cached_metadata_fname, real_blkdev.c_str(), sizeof(cached_metadata_fname));
|
|
|
|
|
cached_off -= CRYPT_FOOTER_OFFSET;
|
|
|
|
|
cached_data = 1;
|
|
|
|
|
} else {
|
|
|
|
|
SLOGE("Cannot get size of block device %s\n", real_blkdev);
|
|
|
|
|
SLOGE("Cannot get size of block device %s\n", real_blkdev.c_str());
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
strlcpy(cached_metadata_fname, key_loc, sizeof(cached_metadata_fname));
|
|
|
|
|
strlcpy(cached_metadata_fname, key_loc.c_str(), sizeof(cached_metadata_fname));
|
|
|
|
|
cached_off = 0;
|
|
|
|
|
cached_data = 1;
|
|
|
|
|
}
|
|
|
|
@ -1595,9 +1614,9 @@ static int cryptfs_restart_internal(int restart_main) {
|
|
|
|
|
char ro_prop[PROPERTY_VALUE_MAX];
|
|
|
|
|
property_get("ro.crypto.readonly", ro_prop, "");
|
|
|
|
|
if (strlen(ro_prop) > 0 && std::stoi(ro_prop)) {
|
|
|
|
|
struct fstab_rec* rec = fs_mgr_get_entry_for_mount_point(fstab_default, DATA_MNT_POINT);
|
|
|
|
|
if (rec) {
|
|
|
|
|
rec->flags |= MS_RDONLY;
|
|
|
|
|
auto entry = GetEntryForMountPoint(&fstab_default, DATA_MNT_POINT);
|
|
|
|
|
if (entry != nullptr) {
|
|
|
|
|
entry->flags |= MS_RDONLY;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1614,7 +1633,7 @@ static int cryptfs_restart_internal(int restart_main) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
bool needs_cp = android::vold::cp_needsCheckpoint();
|
|
|
|
|
while ((mount_rc = fs_mgr_do_mount(fstab_default, DATA_MNT_POINT, crypto_blkdev, 0,
|
|
|
|
|
while ((mount_rc = fs_mgr_do_mount(&fstab_default, DATA_MNT_POINT, crypto_blkdev, 0,
|
|
|
|
|
needs_cp)) != 0) {
|
|
|
|
|
if (mount_rc == FS_MGR_DOMNT_BUSY) {
|
|
|
|
|
/* TODO: invoke something similar to
|
|
|
|
@ -1677,7 +1696,6 @@ int cryptfs_restart(void) {
|
|
|
|
|
static int do_crypto_complete(const char* mount_point) {
|
|
|
|
|
struct crypt_mnt_ftr crypt_ftr;
|
|
|
|
|
char encrypted_state[PROPERTY_VALUE_MAX];
|
|
|
|
|
char key_loc[PROPERTY_VALUE_MAX];
|
|
|
|
|
|
|
|
|
|
property_get("ro.crypto.state", encrypted_state, "");
|
|
|
|
|
if (strcmp(encrypted_state, "encrypted")) {
|
|
|
|
@ -1691,7 +1709,8 @@ static int do_crypto_complete(const char* mount_point) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (get_crypt_ftr_and_key(&crypt_ftr)) {
|
|
|
|
|
fs_mgr_get_crypt_info(fstab_default, key_loc, 0, sizeof(key_loc));
|
|
|
|
|
std::string key_loc;
|
|
|
|
|
get_crypt_info(&key_loc, nullptr);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Only report this error if key_loc is a file and it exists.
|
|
|
|
@ -1700,7 +1719,7 @@ static int do_crypto_complete(const char* mount_point) {
|
|
|
|
|
* a "enter password" screen, or worse, a "press button to wipe the
|
|
|
|
|
* device" screen.
|
|
|
|
|
*/
|
|
|
|
|
if ((key_loc[0] == '/') && (access("key_loc", F_OK) == -1)) {
|
|
|
|
|
if (!key_loc.empty() && key_loc[0] == '/' && (access("key_loc", F_OK) == -1)) {
|
|
|
|
|
SLOGE("master key file does not exist, aborting");
|
|
|
|
|
return CRYPTO_COMPLETE_NOT_ENCRYPTED;
|
|
|
|
|
} else {
|
|
|
|
@ -1733,7 +1752,7 @@ static int test_mount_encrypted_fs(struct crypt_mnt_ftr* crypt_ftr, const char*
|
|
|
|
|
const char* mount_point, const char* label) {
|
|
|
|
|
unsigned char decrypted_master_key[MAX_KEY_LEN];
|
|
|
|
|
char crypto_blkdev[MAXPATHLEN];
|
|
|
|
|
char real_blkdev[MAXPATHLEN];
|
|
|
|
|
std::string real_blkdev;
|
|
|
|
|
char tmp_mount_point[64];
|
|
|
|
|
unsigned int orig_failed_decrypt_count;
|
|
|
|
|
int rc;
|
|
|
|
@ -1757,12 +1776,12 @@ static int test_mount_encrypted_fs(struct crypt_mnt_ftr* crypt_ftr, const char*
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fs_mgr_get_crypt_info(fstab_default, 0, real_blkdev, sizeof(real_blkdev));
|
|
|
|
|
get_crypt_info(nullptr, &real_blkdev);
|
|
|
|
|
|
|
|
|
|
// Create crypto block device - all (non fatal) code paths
|
|
|
|
|
// need it
|
|
|
|
|
if (create_crypto_blk_dev(crypt_ftr, decrypted_master_key, real_blkdev, crypto_blkdev, label,
|
|
|
|
|
0)) {
|
|
|
|
|
if (create_crypto_blk_dev(crypt_ftr, decrypted_master_key, real_blkdev.c_str(), crypto_blkdev,
|
|
|
|
|
label, 0)) {
|
|
|
|
|
SLOGE("Error creating decrypted block device\n");
|
|
|
|
|
rc = -1;
|
|
|
|
|
goto errout;
|
|
|
|
@ -1785,7 +1804,7 @@ static int test_mount_encrypted_fs(struct crypt_mnt_ftr* crypt_ftr, const char*
|
|
|
|
|
* the footer, not the key. */
|
|
|
|
|
snprintf(tmp_mount_point, sizeof(tmp_mount_point), "%s/tmp_mnt", mount_point);
|
|
|
|
|
mkdir(tmp_mount_point, 0755);
|
|
|
|
|
if (fs_mgr_do_mount(fstab_default, DATA_MNT_POINT, crypto_blkdev, tmp_mount_point)) {
|
|
|
|
|
if (fs_mgr_do_mount(&fstab_default, DATA_MNT_POINT, crypto_blkdev, tmp_mount_point)) {
|
|
|
|
|
SLOGE("Error temp mounting decrypted block device\n");
|
|
|
|
|
delete_crypto_blk_dev(label);
|
|
|
|
|
|
|
|
|
@ -2122,14 +2141,15 @@ static int vold_unmountAll(void) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int cryptfs_enable_internal(int crypt_type, const char* passwd, int no_ui) {
|
|
|
|
|
char crypto_blkdev[MAXPATHLEN], real_blkdev[MAXPATHLEN];
|
|
|
|
|
char crypto_blkdev[MAXPATHLEN];
|
|
|
|
|
std::string real_blkdev;
|
|
|
|
|
unsigned char decrypted_master_key[MAX_KEY_LEN];
|
|
|
|
|
int rc = -1, i;
|
|
|
|
|
struct crypt_mnt_ftr crypt_ftr;
|
|
|
|
|
struct crypt_persist_data* pdata;
|
|
|
|
|
char encrypted_state[PROPERTY_VALUE_MAX];
|
|
|
|
|
char lockid[32] = {0};
|
|
|
|
|
char key_loc[PROPERTY_VALUE_MAX];
|
|
|
|
|
std::string key_loc;
|
|
|
|
|
int num_vols;
|
|
|
|
|
off64_t previously_encrypted_upto = 0;
|
|
|
|
|
bool rebootEncryption = false;
|
|
|
|
@ -2172,22 +2192,20 @@ int cryptfs_enable_internal(int crypt_type, const char* passwd, int no_ui) {
|
|
|
|
|
goto error_unencrypted;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO refactor fs_mgr_get_crypt_info to get both in one call
|
|
|
|
|
fs_mgr_get_crypt_info(fstab_default, key_loc, 0, sizeof(key_loc));
|
|
|
|
|
fs_mgr_get_crypt_info(fstab_default, 0, real_blkdev, sizeof(real_blkdev));
|
|
|
|
|
get_crypt_info(&key_loc, &real_blkdev);
|
|
|
|
|
|
|
|
|
|
/* Get the size of the real block device */
|
|
|
|
|
uint64_t nr_sec;
|
|
|
|
|
if (android::vold::GetBlockDev512Sectors(real_blkdev, &nr_sec) != android::OK) {
|
|
|
|
|
SLOGE("Cannot get size of block device %s\n", real_blkdev);
|
|
|
|
|
SLOGE("Cannot get size of block device %s\n", real_blkdev.c_str());
|
|
|
|
|
goto error_unencrypted;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* If doing inplace encryption, make sure the orig fs doesn't include the crypto footer */
|
|
|
|
|
if (!strcmp(key_loc, KEY_IN_FOOTER)) {
|
|
|
|
|
if (key_loc == KEY_IN_FOOTER) {
|
|
|
|
|
uint64_t fs_size_sec, max_fs_size_sec;
|
|
|
|
|
fs_size_sec = get_fs_size(real_blkdev);
|
|
|
|
|
if (fs_size_sec == 0) fs_size_sec = get_f2fs_filesystem_size_sec(real_blkdev);
|
|
|
|
|
fs_size_sec = get_fs_size(real_blkdev.c_str());
|
|
|
|
|
if (fs_size_sec == 0) fs_size_sec = get_f2fs_filesystem_size_sec(real_blkdev.data());
|
|
|
|
|
|
|
|
|
|
max_fs_size_sec = nr_sec - (CRYPT_FOOTER_OFFSET / CRYPT_SECTOR_SIZE);
|
|
|
|
|
|
|
|
|
@ -2260,7 +2278,7 @@ int cryptfs_enable_internal(int crypt_type, const char* passwd, int no_ui) {
|
|
|
|
|
goto error_shutting_down;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!strcmp(key_loc, KEY_IN_FOOTER)) {
|
|
|
|
|
if (key_loc == KEY_IN_FOOTER) {
|
|
|
|
|
crypt_ftr.fs_size = nr_sec - (CRYPT_FOOTER_OFFSET / CRYPT_SECTOR_SIZE);
|
|
|
|
|
} else {
|
|
|
|
|
crypt_ftr.fs_size = nr_sec;
|
|
|
|
@ -2330,7 +2348,7 @@ int cryptfs_enable_internal(int crypt_type, const char* passwd, int no_ui) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
decrypt_master_key(passwd, decrypted_master_key, &crypt_ftr, 0, 0);
|
|
|
|
|
create_crypto_blk_dev(&crypt_ftr, decrypted_master_key, real_blkdev, crypto_blkdev,
|
|
|
|
|
create_crypto_blk_dev(&crypt_ftr, decrypted_master_key, real_blkdev.c_str(), crypto_blkdev,
|
|
|
|
|
CRYPTO_BLOCK_DEVICE, 0);
|
|
|
|
|
|
|
|
|
|
/* If we are continuing, check checksums match */
|
|
|
|
@ -2347,7 +2365,7 @@ int cryptfs_enable_internal(int crypt_type, const char* passwd, int no_ui) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!rc) {
|
|
|
|
|
rc = cryptfs_enable_all_volumes(&crypt_ftr, crypto_blkdev, real_blkdev,
|
|
|
|
|
rc = cryptfs_enable_all_volumes(&crypt_ftr, crypto_blkdev, real_blkdev.data(),
|
|
|
|
|
previously_encrypted_upto);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -2893,6 +2911,6 @@ void cryptfs_clear_password() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int cryptfs_isConvertibleToFBE() {
|
|
|
|
|
struct fstab_rec* rec = fs_mgr_get_entry_for_mount_point(fstab_default, DATA_MNT_POINT);
|
|
|
|
|
return (rec && fs_mgr_is_convertible_to_fbe(rec)) ? 1 : 0;
|
|
|
|
|
auto entry = GetEntryForMountPoint(&fstab_default, DATA_MNT_POINT);
|
|
|
|
|
return entry && entry->fs_mgr_flags.force_fde_or_fbe;
|
|
|
|
|
}
|
|
|
|
|