Remove unused support for partial encryption
Commit87999173dd
("Don't corrupt ssd when encrypting and power fails") added a lot of code to handle pausing in-place conversion from unencrypted => FDE when the battery was low, and resuming it later. It was eventually decided that this wasn't needed, and commit7e17e2d226
("Don't worry about battery levels when encrypting") removed the checks for low battery. This made the partial encryption code unused. So remove it. Note that this was cluttering up the metadata encryption code too, since EncryptInplace.cpp is now shared by both FDE and metadata encryption. Bug: 16868177 Test: see I08fc8465f7962abd698904b5466f3ed080d53953 Change-Id: Ibd2eb08a2aa15938097abcb8a67b5a813c4d76c7
This commit is contained in:
parent
27f3ab89d0
commit
c01995ea3b
4 changed files with 44 additions and 214 deletions
|
@ -32,9 +32,6 @@
|
||||||
#include <android-base/logging.h>
|
#include <android-base/logging.h>
|
||||||
#include <android-base/properties.h>
|
#include <android-base/properties.h>
|
||||||
|
|
||||||
// HORRIBLE HACK, FIXME
|
|
||||||
#include "cryptfs.h"
|
|
||||||
|
|
||||||
// FIXME horrible cut-and-paste code
|
// FIXME horrible cut-and-paste code
|
||||||
static inline int unix_read(int fd, void* buff, int len) {
|
static inline int unix_read(int fd, void* buff, int len) {
|
||||||
return TEMP_FAILURE_RETRY(read(fd, buff, len));
|
return TEMP_FAILURE_RETRY(read(fd, buff, len));
|
||||||
|
@ -54,17 +51,14 @@ static inline int unix_write(int fd, const void* buff, int len) {
|
||||||
struct encryptGroupsData {
|
struct encryptGroupsData {
|
||||||
int realfd;
|
int realfd;
|
||||||
int cryptofd;
|
int cryptofd;
|
||||||
off64_t numblocks;
|
|
||||||
off64_t one_pct, cur_pct, new_pct;
|
off64_t one_pct, cur_pct, new_pct;
|
||||||
off64_t blocks_already_done, tot_numblocks;
|
off64_t blocks_already_done;
|
||||||
off64_t used_blocks_already_done, tot_used_blocks;
|
off64_t used_blocks_already_done, tot_used_blocks;
|
||||||
const char* real_blkdev;
|
const char* real_blkdev;
|
||||||
const char* crypto_blkdev;
|
const char* crypto_blkdev;
|
||||||
int count;
|
int count;
|
||||||
off64_t offset;
|
off64_t offset;
|
||||||
char* buffer;
|
char* buffer;
|
||||||
off64_t last_written_sector;
|
|
||||||
int completed;
|
|
||||||
time_t time_started;
|
time_t time_started;
|
||||||
int remaining_time;
|
int remaining_time;
|
||||||
bool set_progress_properties;
|
bool set_progress_properties;
|
||||||
|
@ -158,8 +152,6 @@ static int flush_outstanding_data(struct encryptGroupsData* data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
data->count = 0;
|
data->count = 0;
|
||||||
data->last_written_sector =
|
|
||||||
(data->offset + data->count) / info.block_size * CRYPT_SECTOR_SIZE - 1;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,7 +230,6 @@ static int encrypt_groups(struct encryptGroupsData* data) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data->completed = 1;
|
|
||||||
rc = 0;
|
rc = 0;
|
||||||
|
|
||||||
errout:
|
errout:
|
||||||
|
@ -249,20 +240,13 @@ errout:
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cryptfs_enable_inplace_ext4(const char* crypto_blkdev, const char* real_blkdev,
|
static int cryptfs_enable_inplace_ext4(const char* crypto_blkdev, const char* real_blkdev,
|
||||||
off64_t size, off64_t* size_already_done, off64_t tot_size,
|
off64_t size, bool set_progress_properties) {
|
||||||
off64_t previously_encrypted_upto,
|
|
||||||
bool set_progress_properties) {
|
|
||||||
u32 i;
|
u32 i;
|
||||||
struct encryptGroupsData data;
|
struct encryptGroupsData data;
|
||||||
int rc; // Can't initialize without causing warning -Wclobbered
|
int rc; // Can't initialize without causing warning -Wclobbered
|
||||||
int retries = RETRY_MOUNT_ATTEMPTS;
|
int retries = RETRY_MOUNT_ATTEMPTS;
|
||||||
struct timespec time_started = {0};
|
struct timespec time_started = {0};
|
||||||
|
|
||||||
if (previously_encrypted_upto > *size_already_done) {
|
|
||||||
LOG(DEBUG) << "Not fast encrypting since resuming part way through";
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(&data, 0, sizeof(data));
|
memset(&data, 0, sizeof(data));
|
||||||
data.real_blkdev = real_blkdev;
|
data.real_blkdev = real_blkdev;
|
||||||
data.crypto_blkdev = crypto_blkdev;
|
data.crypto_blkdev = crypto_blkdev;
|
||||||
|
@ -302,13 +286,11 @@ static int cryptfs_enable_inplace_ext4(const char* crypto_blkdev, const char* re
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
|
||||||
data.numblocks = size / CRYPT_SECTORS_PER_BUFSIZE;
|
data.blocks_already_done = 0;
|
||||||
data.tot_numblocks = tot_size / CRYPT_SECTORS_PER_BUFSIZE;
|
|
||||||
data.blocks_already_done = *size_already_done / CRYPT_SECTORS_PER_BUFSIZE;
|
|
||||||
|
|
||||||
LOG(INFO) << "Encrypting ext4 filesystem in place...";
|
LOG(INFO) << "Encrypting ext4 filesystem in place...";
|
||||||
|
|
||||||
data.tot_used_blocks = data.numblocks;
|
data.tot_used_blocks = size / CRYPT_SECTORS_PER_BUFSIZE;
|
||||||
for (i = 0; i < aux_info.groups; ++i) {
|
for (i = 0; i < aux_info.groups; ++i) {
|
||||||
data.tot_used_blocks -= aux_info.bg_desc[i].bg_free_blocks_count;
|
data.tot_used_blocks -= aux_info.bg_desc[i].bg_free_blocks_count;
|
||||||
}
|
}
|
||||||
|
@ -329,7 +311,6 @@ static int cryptfs_enable_inplace_ext4(const char* crypto_blkdev, const char* re
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
|
||||||
*size_already_done += data.completed ? size : data.last_written_sector;
|
|
||||||
rc = 0;
|
rc = 0;
|
||||||
|
|
||||||
errout:
|
errout:
|
||||||
|
@ -388,18 +369,12 @@ static int encrypt_one_block_f2fs(u64 pos, void* data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cryptfs_enable_inplace_f2fs(const char* crypto_blkdev, const char* real_blkdev,
|
static int cryptfs_enable_inplace_f2fs(const char* crypto_blkdev, const char* real_blkdev,
|
||||||
off64_t size, off64_t* size_already_done, off64_t tot_size,
|
off64_t size, bool set_progress_properties) {
|
||||||
off64_t previously_encrypted_upto,
|
|
||||||
bool set_progress_properties) {
|
|
||||||
struct encryptGroupsData data;
|
struct encryptGroupsData data;
|
||||||
struct f2fs_info* f2fs_info = NULL;
|
struct f2fs_info* f2fs_info = NULL;
|
||||||
int rc = ENABLE_INPLACE_ERR_OTHER;
|
int rc = ENABLE_INPLACE_ERR_OTHER;
|
||||||
struct timespec time_started = {0};
|
struct timespec time_started = {0};
|
||||||
|
|
||||||
if (previously_encrypted_upto > *size_already_done) {
|
|
||||||
LOG(DEBUG) << "Not fast encrypting since resuming part way through";
|
|
||||||
return ENABLE_INPLACE_ERR_OTHER;
|
|
||||||
}
|
|
||||||
memset(&data, 0, sizeof(data));
|
memset(&data, 0, sizeof(data));
|
||||||
data.real_blkdev = real_blkdev;
|
data.real_blkdev = real_blkdev;
|
||||||
data.crypto_blkdev = crypto_blkdev;
|
data.crypto_blkdev = crypto_blkdev;
|
||||||
|
@ -420,9 +395,7 @@ static int cryptfs_enable_inplace_f2fs(const char* crypto_blkdev, const char* re
|
||||||
f2fs_info = generate_f2fs_info(data.realfd);
|
f2fs_info = generate_f2fs_info(data.realfd);
|
||||||
if (!f2fs_info) goto errout;
|
if (!f2fs_info) goto errout;
|
||||||
|
|
||||||
data.numblocks = size / CRYPT_SECTORS_PER_BUFSIZE;
|
data.blocks_already_done = 0;
|
||||||
data.tot_numblocks = tot_size / CRYPT_SECTORS_PER_BUFSIZE;
|
|
||||||
data.blocks_already_done = *size_already_done / CRYPT_SECTORS_PER_BUFSIZE;
|
|
||||||
|
|
||||||
data.tot_used_blocks = get_num_blocks_used(f2fs_info);
|
data.tot_used_blocks = get_num_blocks_used(f2fs_info);
|
||||||
|
|
||||||
|
@ -453,7 +426,6 @@ static int cryptfs_enable_inplace_f2fs(const char* crypto_blkdev, const char* re
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
|
||||||
*size_already_done += size;
|
|
||||||
rc = 0;
|
rc = 0;
|
||||||
|
|
||||||
errout:
|
errout:
|
||||||
|
@ -469,15 +441,12 @@ errout:
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cryptfs_enable_inplace_full(const char* crypto_blkdev, const char* real_blkdev,
|
static int cryptfs_enable_inplace_full(const char* crypto_blkdev, const char* real_blkdev,
|
||||||
off64_t size, off64_t* size_already_done, off64_t tot_size,
|
off64_t size, bool set_progress_properties) {
|
||||||
off64_t previously_encrypted_upto,
|
|
||||||
bool set_progress_properties) {
|
|
||||||
int realfd, cryptofd;
|
int realfd, cryptofd;
|
||||||
char* buf[CRYPT_INPLACE_BUFSIZE];
|
char* buf[CRYPT_INPLACE_BUFSIZE];
|
||||||
int rc = ENABLE_INPLACE_ERR_OTHER;
|
int rc = ENABLE_INPLACE_ERR_OTHER;
|
||||||
off64_t numblocks, i, remainder;
|
off64_t numblocks, i, remainder;
|
||||||
off64_t one_pct, cur_pct, new_pct;
|
off64_t one_pct, cur_pct, new_pct;
|
||||||
off64_t blocks_already_done, tot_numblocks;
|
|
||||||
|
|
||||||
if ((realfd = open(real_blkdev, O_RDONLY | O_CLOEXEC)) < 0) {
|
if ((realfd = open(real_blkdev, O_RDONLY | O_CLOEXEC)) < 0) {
|
||||||
PLOG(ERROR) << "Error opening real_blkdev " << real_blkdev << " for inplace encrypt";
|
PLOG(ERROR) << "Error opening real_blkdev " << real_blkdev << " for inplace encrypt";
|
||||||
|
@ -497,43 +466,14 @@ static int cryptfs_enable_inplace_full(const char* crypto_blkdev, const char* re
|
||||||
*/
|
*/
|
||||||
numblocks = size / CRYPT_SECTORS_PER_BUFSIZE;
|
numblocks = size / CRYPT_SECTORS_PER_BUFSIZE;
|
||||||
remainder = size % CRYPT_SECTORS_PER_BUFSIZE;
|
remainder = size % CRYPT_SECTORS_PER_BUFSIZE;
|
||||||
tot_numblocks = tot_size / CRYPT_SECTORS_PER_BUFSIZE;
|
|
||||||
blocks_already_done = *size_already_done / CRYPT_SECTORS_PER_BUFSIZE;
|
|
||||||
|
|
||||||
LOG(ERROR) << "Encrypting filesystem in place...";
|
LOG(ERROR) << "Encrypting filesystem in place...";
|
||||||
|
|
||||||
i = previously_encrypted_upto + 1 - *size_already_done;
|
one_pct = numblocks / 100;
|
||||||
|
|
||||||
if (lseek64(realfd, i * CRYPT_SECTOR_SIZE, SEEK_SET) < 0) {
|
|
||||||
PLOG(ERROR) << "Cannot seek to previously encrypted point on " << real_blkdev;
|
|
||||||
goto errout;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lseek64(cryptofd, i * CRYPT_SECTOR_SIZE, SEEK_SET) < 0) {
|
|
||||||
PLOG(ERROR) << "Cannot seek to previously encrypted point on " << crypto_blkdev;
|
|
||||||
goto errout;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (; i < size && i % CRYPT_SECTORS_PER_BUFSIZE != 0; ++i) {
|
|
||||||
if (unix_read(realfd, buf, CRYPT_SECTOR_SIZE) <= 0) {
|
|
||||||
PLOG(ERROR) << "Error reading initial sectors from real_blkdev " << real_blkdev
|
|
||||||
<< " for inplace encrypt";
|
|
||||||
goto errout;
|
|
||||||
}
|
|
||||||
if (unix_write(cryptofd, buf, CRYPT_SECTOR_SIZE) <= 0) {
|
|
||||||
PLOG(ERROR) << "Error writing initial sectors to crypto_blkdev " << crypto_blkdev
|
|
||||||
<< " for inplace encrypt";
|
|
||||||
goto errout;
|
|
||||||
} else {
|
|
||||||
LOG(INFO) << "Encrypted 1 block at " << i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
one_pct = tot_numblocks / 100;
|
|
||||||
cur_pct = 0;
|
cur_pct = 0;
|
||||||
/* process the majority of the filesystem in blocks */
|
/* process the majority of the filesystem in blocks */
|
||||||
for (i /= CRYPT_SECTORS_PER_BUFSIZE; i < numblocks; i++) {
|
for (i = 0; i < numblocks; i++) {
|
||||||
new_pct = (i + blocks_already_done) / one_pct;
|
new_pct = i / one_pct;
|
||||||
if (set_progress_properties && new_pct > cur_pct) {
|
if (set_progress_properties && new_pct > cur_pct) {
|
||||||
char property_buf[8];
|
char property_buf[8];
|
||||||
|
|
||||||
|
@ -570,7 +510,6 @@ static int cryptfs_enable_inplace_full(const char* crypto_blkdev, const char* re
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*size_already_done += size;
|
|
||||||
rc = 0;
|
rc = 0;
|
||||||
|
|
||||||
errout:
|
errout:
|
||||||
|
@ -582,36 +521,23 @@ errout:
|
||||||
|
|
||||||
/* returns on of the ENABLE_INPLACE_* return codes */
|
/* returns on of the ENABLE_INPLACE_* return codes */
|
||||||
int cryptfs_enable_inplace(const char* crypto_blkdev, const char* real_blkdev, off64_t size,
|
int cryptfs_enable_inplace(const char* crypto_blkdev, const char* real_blkdev, off64_t size,
|
||||||
off64_t* size_already_done, off64_t tot_size,
|
bool set_progress_properties) {
|
||||||
off64_t previously_encrypted_upto, bool set_progress_properties) {
|
|
||||||
int rc_ext4, rc_f2fs, rc_full;
|
int rc_ext4, rc_f2fs, rc_full;
|
||||||
LOG(DEBUG) << "cryptfs_enable_inplace(" << crypto_blkdev << ", " << real_blkdev << ", " << size
|
LOG(DEBUG) << "cryptfs_enable_inplace(" << crypto_blkdev << ", " << real_blkdev << ", " << size
|
||||||
<< ", " << size_already_done << ", " << tot_size << ", " << previously_encrypted_upto
|
|
||||||
<< ", " << set_progress_properties << ")";
|
<< ", " << set_progress_properties << ")";
|
||||||
if (previously_encrypted_upto) {
|
|
||||||
LOG(DEBUG) << "Continuing encryption from " << previously_encrypted_upto;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*size_already_done + size < previously_encrypted_upto) {
|
|
||||||
LOG(DEBUG) << "cryptfs_enable_inplace already done";
|
|
||||||
*size_already_done += size;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO: identify filesystem type.
|
/* TODO: identify filesystem type.
|
||||||
* As is, cryptfs_enable_inplace_ext4 will fail on an f2fs partition, and
|
* As is, cryptfs_enable_inplace_ext4 will fail on an f2fs partition, and
|
||||||
* then we will drop down to cryptfs_enable_inplace_f2fs.
|
* then we will drop down to cryptfs_enable_inplace_f2fs.
|
||||||
* */
|
* */
|
||||||
if ((rc_ext4 = cryptfs_enable_inplace_ext4(crypto_blkdev, real_blkdev, size, size_already_done,
|
if ((rc_ext4 = cryptfs_enable_inplace_ext4(crypto_blkdev, real_blkdev, size,
|
||||||
tot_size, previously_encrypted_upto,
|
|
||||||
set_progress_properties)) == 0) {
|
set_progress_properties)) == 0) {
|
||||||
LOG(DEBUG) << "cryptfs_enable_inplace_ext4 success";
|
LOG(DEBUG) << "cryptfs_enable_inplace_ext4 success";
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
LOG(DEBUG) << "cryptfs_enable_inplace_ext4()=" << rc_ext4;
|
LOG(DEBUG) << "cryptfs_enable_inplace_ext4()=" << rc_ext4;
|
||||||
|
|
||||||
if ((rc_f2fs = cryptfs_enable_inplace_f2fs(crypto_blkdev, real_blkdev, size, size_already_done,
|
if ((rc_f2fs = cryptfs_enable_inplace_f2fs(crypto_blkdev, real_blkdev, size,
|
||||||
tot_size, previously_encrypted_upto,
|
|
||||||
set_progress_properties)) == 0) {
|
set_progress_properties)) == 0) {
|
||||||
LOG(DEBUG) << "cryptfs_enable_inplace_f2fs success";
|
LOG(DEBUG) << "cryptfs_enable_inplace_f2fs success";
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -619,8 +545,7 @@ int cryptfs_enable_inplace(const char* crypto_blkdev, const char* real_blkdev, o
|
||||||
LOG(DEBUG) << "cryptfs_enable_inplace_f2fs()=" << rc_f2fs;
|
LOG(DEBUG) << "cryptfs_enable_inplace_f2fs()=" << rc_f2fs;
|
||||||
|
|
||||||
rc_full =
|
rc_full =
|
||||||
cryptfs_enable_inplace_full(crypto_blkdev, real_blkdev, size, size_already_done, tot_size,
|
cryptfs_enable_inplace_full(crypto_blkdev, real_blkdev, size, set_progress_properties);
|
||||||
previously_encrypted_upto, set_progress_properties);
|
|
||||||
LOG(DEBUG) << "cryptfs_enable_inplace_full()=" << rc_full;
|
LOG(DEBUG) << "cryptfs_enable_inplace_full()=" << rc_full;
|
||||||
|
|
||||||
/* Hack for b/17898962, the following is the symptom... */
|
/* Hack for b/17898962, the following is the symptom... */
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
#define ENABLE_INPLACE_ERR_DEV (-2) /* crypto_blkdev issue */
|
#define ENABLE_INPLACE_ERR_DEV (-2) /* crypto_blkdev issue */
|
||||||
|
|
||||||
int cryptfs_enable_inplace(const char* crypto_blkdev, const char* real_blkdev, off64_t size,
|
int cryptfs_enable_inplace(const char* crypto_blkdev, const char* real_blkdev, off64_t size,
|
||||||
off64_t* size_already_done, off64_t tot_size,
|
bool set_progress_properties);
|
||||||
off64_t previously_encrypted_upto, bool set_progress_properties);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -307,17 +307,11 @@ bool fscrypt_mount_metadata_encrypted(const std::string& blk_device, const std::
|
||||||
// FIXME handle the corrupt case
|
// FIXME handle the corrupt case
|
||||||
if (needs_encrypt) {
|
if (needs_encrypt) {
|
||||||
LOG(INFO) << "Beginning inplace encryption, nr_sec: " << nr_sec;
|
LOG(INFO) << "Beginning inplace encryption, nr_sec: " << nr_sec;
|
||||||
off64_t size_already_done = 0;
|
auto rc = cryptfs_enable_inplace(crypto_blkdev.data(), blk_device.data(), nr_sec, false);
|
||||||
auto rc = cryptfs_enable_inplace(crypto_blkdev.data(), blk_device.data(), nr_sec,
|
|
||||||
&size_already_done, nr_sec, 0, false);
|
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
LOG(ERROR) << "Inplace crypto failed with code: " << rc;
|
LOG(ERROR) << "Inplace crypto failed with code: " << rc;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (static_cast<uint64_t>(size_already_done) != nr_sec) {
|
|
||||||
LOG(ERROR) << "Inplace crypto only got up to sector: " << size_already_done;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
LOG(INFO) << "Inplace encryption complete";
|
LOG(INFO) << "Inplace encryption complete";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
108
cryptfs.cpp
108
cryptfs.cpp
|
@ -98,9 +98,7 @@ using namespace std::chrono_literals;
|
||||||
|
|
||||||
/* definitions of flags in the structure below */
|
/* definitions of flags in the structure below */
|
||||||
#define CRYPT_MNT_KEY_UNENCRYPTED 0x1 /* The key for the partition is not encrypted. */
|
#define CRYPT_MNT_KEY_UNENCRYPTED 0x1 /* The key for the partition is not encrypted. */
|
||||||
#define CRYPT_ENCRYPTION_IN_PROGRESS \
|
#define CRYPT_ENCRYPTION_IN_PROGRESS 0x2 /* no longer used */
|
||||||
0x2 /* Encryption partially completed, \
|
|
||||||
encrypted_upto valid*/
|
|
||||||
#define CRYPT_INCONSISTENT_STATE \
|
#define CRYPT_INCONSISTENT_STATE \
|
||||||
0x4 /* Set when starting encryption, clear when \
|
0x4 /* Set when starting encryption, clear when \
|
||||||
exit cleanly, either through success or \
|
exit cleanly, either through success or \
|
||||||
|
@ -195,12 +193,8 @@ struct crypt_mnt_ftr {
|
||||||
__le8 N_factor; /* (1 << N) */
|
__le8 N_factor; /* (1 << N) */
|
||||||
__le8 r_factor; /* (1 << r) */
|
__le8 r_factor; /* (1 << r) */
|
||||||
__le8 p_factor; /* (1 << p) */
|
__le8 p_factor; /* (1 << p) */
|
||||||
__le64 encrypted_upto; /* If we are in state CRYPT_ENCRYPTION_IN_PROGRESS and
|
__le64 encrypted_upto; /* no longer used */
|
||||||
we have to stop (e.g. power low) this is the last
|
__le8 hash_first_block[SHA256_DIGEST_LENGTH]; /* no longer used */
|
||||||
encrypted 512 byte sector.*/
|
|
||||||
__le8 hash_first_block[SHA256_DIGEST_LENGTH]; /* When CRYPT_ENCRYPTION_IN_PROGRESS
|
|
||||||
set, hash of first block, used
|
|
||||||
to validate before continuing*/
|
|
||||||
|
|
||||||
/* key_master key, used to sign the derived key which is then used to generate
|
/* key_master key, used to sign the derived key which is then used to generate
|
||||||
* the intermediate key
|
* the intermediate key
|
||||||
|
@ -2069,41 +2063,11 @@ static int cryptfs_init_crypt_mnt_ftr(struct crypt_mnt_ftr* ftr) {
|
||||||
|
|
||||||
#define FRAMEWORK_BOOT_WAIT 60
|
#define FRAMEWORK_BOOT_WAIT 60
|
||||||
|
|
||||||
static int cryptfs_SHA256_fileblock(const char* filename, __le8* buf) {
|
|
||||||
int fd = open(filename, O_RDONLY | O_CLOEXEC);
|
|
||||||
if (fd == -1) {
|
|
||||||
SLOGE("Error opening file %s", filename);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
char block[CRYPT_INPLACE_BUFSIZE];
|
|
||||||
memset(block, 0, sizeof(block));
|
|
||||||
if (unix_read(fd, block, sizeof(block)) < 0) {
|
|
||||||
SLOGE("Error reading file %s", filename);
|
|
||||||
close(fd);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
close(fd);
|
|
||||||
|
|
||||||
SHA256_CTX c;
|
|
||||||
SHA256_Init(&c);
|
|
||||||
SHA256_Update(&c, block, sizeof(block));
|
|
||||||
SHA256_Final(buf, &c);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int cryptfs_enable_all_volumes(struct crypt_mnt_ftr* crypt_ftr, const char* crypto_blkdev,
|
static int cryptfs_enable_all_volumes(struct crypt_mnt_ftr* crypt_ftr, const char* crypto_blkdev,
|
||||||
const char* real_blkdev, int previously_encrypted_upto) {
|
const char* real_blkdev) {
|
||||||
off64_t cur_encryption_done = 0, tot_encryption_size = 0;
|
|
||||||
int rc = -1;
|
int rc = -1;
|
||||||
|
|
||||||
/* The size of the userdata partition, and add in the vold volumes below */
|
rc = cryptfs_enable_inplace(crypto_blkdev, real_blkdev, crypt_ftr->fs_size, true);
|
||||||
tot_encryption_size = crypt_ftr->fs_size;
|
|
||||||
|
|
||||||
rc = cryptfs_enable_inplace(crypto_blkdev, real_blkdev, crypt_ftr->fs_size, &cur_encryption_done,
|
|
||||||
tot_encryption_size, previously_encrypted_upto, true);
|
|
||||||
|
|
||||||
if (rc == ENABLE_INPLACE_ERR_DEV) {
|
if (rc == ENABLE_INPLACE_ERR_DEV) {
|
||||||
/* Hack for b/17898962 */
|
/* Hack for b/17898962 */
|
||||||
|
@ -2112,10 +2076,8 @@ static int cryptfs_enable_all_volumes(struct crypt_mnt_ftr* crypt_ftr, const cha
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!rc) {
|
if (!rc) {
|
||||||
crypt_ftr->encrypted_upto = cur_encryption_done;
|
crypt_ftr->encrypted_upto = crypt_ftr->fs_size;
|
||||||
}
|
|
||||||
|
|
||||||
if (!rc && crypt_ftr->encrypted_upto == crypt_ftr->fs_size) {
|
|
||||||
/* The inplace routine never actually sets the progress to 100% due
|
/* The inplace routine never actually sets the progress to 100% due
|
||||||
* to the round down nature of integer division, so set it here */
|
* to the round down nature of integer division, so set it here */
|
||||||
property_set("vold.encrypt_progress", "100");
|
property_set("vold.encrypt_progress", "100");
|
||||||
|
@ -2140,26 +2102,12 @@ int cryptfs_enable_internal(int crypt_type, const char* passwd, int no_ui) {
|
||||||
char lockid[32] = {0};
|
char lockid[32] = {0};
|
||||||
std::string key_loc;
|
std::string key_loc;
|
||||||
int num_vols;
|
int num_vols;
|
||||||
off64_t previously_encrypted_upto = 0;
|
|
||||||
bool rebootEncryption = false;
|
bool rebootEncryption = false;
|
||||||
bool onlyCreateHeader = false;
|
bool onlyCreateHeader = false;
|
||||||
std::unique_ptr<android::wakelock::WakeLock> wakeLock = nullptr;
|
std::unique_ptr<android::wakelock::WakeLock> wakeLock = nullptr;
|
||||||
|
|
||||||
if (get_crypt_ftr_and_key(&crypt_ftr) == 0) {
|
if (get_crypt_ftr_and_key(&crypt_ftr) == 0) {
|
||||||
if (crypt_ftr.flags & CRYPT_ENCRYPTION_IN_PROGRESS) {
|
if (crypt_ftr.flags & CRYPT_FORCE_ENCRYPTION) {
|
||||||
/* An encryption was underway and was interrupted */
|
|
||||||
previously_encrypted_upto = crypt_ftr.encrypted_upto;
|
|
||||||
crypt_ftr.encrypted_upto = 0;
|
|
||||||
crypt_ftr.flags &= ~CRYPT_ENCRYPTION_IN_PROGRESS;
|
|
||||||
|
|
||||||
/* At this point, we are in an inconsistent state. Until we successfully
|
|
||||||
complete encryption, a reboot will leave us broken. So mark the
|
|
||||||
encryption failed in case that happens.
|
|
||||||
On successfully completing encryption, remove this flag */
|
|
||||||
crypt_ftr.flags |= CRYPT_INCONSISTENT_STATE;
|
|
||||||
|
|
||||||
put_crypt_ftr_and_key(&crypt_ftr);
|
|
||||||
} else if (crypt_ftr.flags & CRYPT_FORCE_ENCRYPTION) {
|
|
||||||
if (!check_ftr_sha(&crypt_ftr)) {
|
if (!check_ftr_sha(&crypt_ftr)) {
|
||||||
memset(&crypt_ftr, 0, sizeof(crypt_ftr));
|
memset(&crypt_ftr, 0, sizeof(crypt_ftr));
|
||||||
put_crypt_ftr_and_key(&crypt_ftr);
|
put_crypt_ftr_and_key(&crypt_ftr);
|
||||||
|
@ -2177,7 +2125,7 @@ int cryptfs_enable_internal(int crypt_type, const char* passwd, int no_ui) {
|
||||||
}
|
}
|
||||||
|
|
||||||
property_get("ro.crypto.state", encrypted_state, "");
|
property_get("ro.crypto.state", encrypted_state, "");
|
||||||
if (!strcmp(encrypted_state, "encrypted") && !previously_encrypted_upto) {
|
if (!strcmp(encrypted_state, "encrypted")) {
|
||||||
SLOGE("Device is already running encrypted, aborting");
|
SLOGE("Device is already running encrypted, aborting");
|
||||||
goto error_unencrypted;
|
goto error_unencrypted;
|
||||||
}
|
}
|
||||||
|
@ -2264,7 +2212,7 @@ int cryptfs_enable_internal(int crypt_type, const char* passwd, int no_ui) {
|
||||||
|
|
||||||
/* Start the actual work of making an encrypted filesystem */
|
/* Start the actual work of making an encrypted filesystem */
|
||||||
/* Initialize a crypt_mnt_ftr for the partition */
|
/* Initialize a crypt_mnt_ftr for the partition */
|
||||||
if (previously_encrypted_upto == 0 && !rebootEncryption) {
|
if (!rebootEncryption) {
|
||||||
if (cryptfs_init_crypt_mnt_ftr(&crypt_ftr)) {
|
if (cryptfs_init_crypt_mnt_ftr(&crypt_ftr)) {
|
||||||
goto error_shutting_down;
|
goto error_shutting_down;
|
||||||
}
|
}
|
||||||
|
@ -2342,32 +2290,7 @@ int cryptfs_enable_internal(int crypt_type, const char* passwd, int no_ui) {
|
||||||
create_crypto_blk_dev(&crypt_ftr, decrypted_master_key, real_blkdev.c_str(), &crypto_blkdev,
|
create_crypto_blk_dev(&crypt_ftr, decrypted_master_key, real_blkdev.c_str(), &crypto_blkdev,
|
||||||
CRYPTO_BLOCK_DEVICE, 0);
|
CRYPTO_BLOCK_DEVICE, 0);
|
||||||
|
|
||||||
/* If we are continuing, check checksums match */
|
rc = cryptfs_enable_all_volumes(&crypt_ftr, crypto_blkdev.c_str(), real_blkdev.data());
|
||||||
rc = 0;
|
|
||||||
if (previously_encrypted_upto) {
|
|
||||||
__le8 hash_first_block[SHA256_DIGEST_LENGTH];
|
|
||||||
rc = cryptfs_SHA256_fileblock(crypto_blkdev.c_str(), hash_first_block);
|
|
||||||
|
|
||||||
if (!rc &&
|
|
||||||
memcmp(hash_first_block, crypt_ftr.hash_first_block, sizeof(hash_first_block)) != 0) {
|
|
||||||
SLOGE("Checksums do not match - trigger wipe");
|
|
||||||
rc = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!rc) {
|
|
||||||
rc = cryptfs_enable_all_volumes(&crypt_ftr, crypto_blkdev.c_str(), real_blkdev.data(),
|
|
||||||
previously_encrypted_upto);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Calculate checksum if we are not finished */
|
|
||||||
if (!rc && crypt_ftr.encrypted_upto != crypt_ftr.fs_size) {
|
|
||||||
rc = cryptfs_SHA256_fileblock(crypto_blkdev.c_str(), crypt_ftr.hash_first_block);
|
|
||||||
if (rc) {
|
|
||||||
SLOGE("Error calculating checksum for continuing encryption");
|
|
||||||
rc = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Undo the dm-crypt mapping whether we succeed or not */
|
/* Undo the dm-crypt mapping whether we succeed or not */
|
||||||
delete_crypto_blk_dev(CRYPTO_BLOCK_DEVICE);
|
delete_crypto_blk_dev(CRYPTO_BLOCK_DEVICE);
|
||||||
|
@ -2376,15 +2299,8 @@ int cryptfs_enable_internal(int crypt_type, const char* passwd, int no_ui) {
|
||||||
/* Success */
|
/* Success */
|
||||||
crypt_ftr.flags &= ~CRYPT_INCONSISTENT_STATE;
|
crypt_ftr.flags &= ~CRYPT_INCONSISTENT_STATE;
|
||||||
|
|
||||||
if (crypt_ftr.encrypted_upto != crypt_ftr.fs_size) {
|
|
||||||
SLOGD("Encrypted up to sector %lld - will continue after reboot",
|
|
||||||
crypt_ftr.encrypted_upto);
|
|
||||||
crypt_ftr.flags |= CRYPT_ENCRYPTION_IN_PROGRESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
put_crypt_ftr_and_key(&crypt_ftr);
|
put_crypt_ftr_and_key(&crypt_ftr);
|
||||||
|
|
||||||
if (crypt_ftr.encrypted_upto == crypt_ftr.fs_size) {
|
|
||||||
char value[PROPERTY_VALUE_MAX];
|
char value[PROPERTY_VALUE_MAX];
|
||||||
property_get("ro.crypto.state", value, "");
|
property_get("ro.crypto.state", value, "");
|
||||||
if (!strcmp(value, "")) {
|
if (!strcmp(value, "")) {
|
||||||
|
@ -2407,10 +2323,6 @@ int cryptfs_enable_internal(int crypt_type, const char* passwd, int no_ui) {
|
||||||
sleep(2); /* Give the UI a chance to show 100% progress */
|
sleep(2); /* Give the UI a chance to show 100% progress */
|
||||||
cryptfs_reboot(RebootType::reboot);
|
cryptfs_reboot(RebootType::reboot);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
sleep(2); /* Partially encrypted, ensure writes flushed to ssd */
|
|
||||||
cryptfs_reboot(RebootType::shutdown);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
char value[PROPERTY_VALUE_MAX];
|
char value[PROPERTY_VALUE_MAX];
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue