From c01995ea3bfe357e8e85d3fe946014f675a0683f Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Tue, 3 Nov 2020 14:11:00 -0800 Subject: [PATCH] Remove unused support for partial encryption Commit 87999173dd79 ("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 commit 7e17e2d22678 ("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 --- EncryptInplace.cpp | 103 +++++--------------------------- EncryptInplace.h | 3 +- MetadataCrypt.cpp | 8 +-- cryptfs.cpp | 144 +++++++++------------------------------------ 4 files changed, 44 insertions(+), 214 deletions(-) diff --git a/EncryptInplace.cpp b/EncryptInplace.cpp index bdb2da7..438f959 100644 --- a/EncryptInplace.cpp +++ b/EncryptInplace.cpp @@ -32,9 +32,6 @@ #include #include -// HORRIBLE HACK, FIXME -#include "cryptfs.h" - // FIXME horrible cut-and-paste code static inline int unix_read(int fd, void* buff, int 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 { int realfd; int cryptofd; - off64_t numblocks; 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; const char* real_blkdev; const char* crypto_blkdev; int count; off64_t offset; char* buffer; - off64_t last_written_sector; - int completed; time_t time_started; int remaining_time; bool set_progress_properties; @@ -158,8 +152,6 @@ static int flush_outstanding_data(struct encryptGroupsData* data) { } data->count = 0; - data->last_written_sector = - (data->offset + data->count) / info.block_size * CRYPT_SECTOR_SIZE - 1; return 0; } @@ -238,7 +230,6 @@ static int encrypt_groups(struct encryptGroupsData* data) { } } - data->completed = 1; rc = 0; errout: @@ -249,20 +240,13 @@ errout: } 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 previously_encrypted_upto, - bool set_progress_properties) { + off64_t size, bool set_progress_properties) { u32 i; struct encryptGroupsData data; int rc; // Can't initialize without causing warning -Wclobbered int retries = RETRY_MOUNT_ATTEMPTS; 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)); data.real_blkdev = real_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; } - data.numblocks = size / CRYPT_SECTORS_PER_BUFSIZE; - data.tot_numblocks = tot_size / CRYPT_SECTORS_PER_BUFSIZE; - data.blocks_already_done = *size_already_done / CRYPT_SECTORS_PER_BUFSIZE; + data.blocks_already_done = 0; 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) { 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; } - *size_already_done += data.completed ? size : data.last_written_sector; rc = 0; 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, - off64_t size, off64_t* size_already_done, off64_t tot_size, - off64_t previously_encrypted_upto, - bool set_progress_properties) { + off64_t size, bool set_progress_properties) { struct encryptGroupsData data; struct f2fs_info* f2fs_info = NULL; int rc = ENABLE_INPLACE_ERR_OTHER; 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)); data.real_blkdev = real_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); if (!f2fs_info) goto errout; - data.numblocks = size / CRYPT_SECTORS_PER_BUFSIZE; - data.tot_numblocks = tot_size / CRYPT_SECTORS_PER_BUFSIZE; - data.blocks_already_done = *size_already_done / CRYPT_SECTORS_PER_BUFSIZE; + data.blocks_already_done = 0; 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; } - *size_already_done += size; rc = 0; errout: @@ -469,15 +441,12 @@ errout: } 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 previously_encrypted_upto, - bool set_progress_properties) { + off64_t size, bool set_progress_properties) { int realfd, cryptofd; char* buf[CRYPT_INPLACE_BUFSIZE]; int rc = ENABLE_INPLACE_ERR_OTHER; off64_t numblocks, i, remainder; 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) { 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; 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..."; - i = previously_encrypted_upto + 1 - *size_already_done; - - 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; + one_pct = numblocks / 100; cur_pct = 0; /* process the majority of the filesystem in blocks */ - for (i /= CRYPT_SECTORS_PER_BUFSIZE; i < numblocks; i++) { - new_pct = (i + blocks_already_done) / one_pct; + for (i = 0; i < numblocks; i++) { + new_pct = i / one_pct; if (set_progress_properties && new_pct > cur_pct) { 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; errout: @@ -582,36 +521,23 @@ errout: /* returns on of the ENABLE_INPLACE_* return codes */ int cryptfs_enable_inplace(const char* crypto_blkdev, const char* real_blkdev, off64_t size, - off64_t* size_already_done, off64_t tot_size, - off64_t previously_encrypted_upto, bool set_progress_properties) { + bool set_progress_properties) { int rc_ext4, rc_f2fs, rc_full; LOG(DEBUG) << "cryptfs_enable_inplace(" << crypto_blkdev << ", " << real_blkdev << ", " << size - << ", " << size_already_done << ", " << tot_size << ", " << previously_encrypted_upto << ", " << 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. * As is, cryptfs_enable_inplace_ext4 will fail on an f2fs partition, and * 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, - tot_size, previously_encrypted_upto, + if ((rc_ext4 = cryptfs_enable_inplace_ext4(crypto_blkdev, real_blkdev, size, set_progress_properties)) == 0) { LOG(DEBUG) << "cryptfs_enable_inplace_ext4 success"; return 0; } LOG(DEBUG) << "cryptfs_enable_inplace_ext4()=" << rc_ext4; - if ((rc_f2fs = cryptfs_enable_inplace_f2fs(crypto_blkdev, real_blkdev, size, size_already_done, - tot_size, previously_encrypted_upto, + if ((rc_f2fs = cryptfs_enable_inplace_f2fs(crypto_blkdev, real_blkdev, size, set_progress_properties)) == 0) { LOG(DEBUG) << "cryptfs_enable_inplace_f2fs success"; 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; rc_full = - cryptfs_enable_inplace_full(crypto_blkdev, real_blkdev, size, size_already_done, tot_size, - previously_encrypted_upto, set_progress_properties); + cryptfs_enable_inplace_full(crypto_blkdev, real_blkdev, size, set_progress_properties); LOG(DEBUG) << "cryptfs_enable_inplace_full()=" << rc_full; /* Hack for b/17898962, the following is the symptom... */ diff --git a/EncryptInplace.h b/EncryptInplace.h index a2b46cf..5967632 100644 --- a/EncryptInplace.h +++ b/EncryptInplace.h @@ -30,7 +30,6 @@ #define ENABLE_INPLACE_ERR_DEV (-2) /* crypto_blkdev issue */ int cryptfs_enable_inplace(const char* crypto_blkdev, const char* real_blkdev, off64_t size, - off64_t* size_already_done, off64_t tot_size, - off64_t previously_encrypted_upto, bool set_progress_properties); + bool set_progress_properties); #endif diff --git a/MetadataCrypt.cpp b/MetadataCrypt.cpp index 5950425..e6497e5 100644 --- a/MetadataCrypt.cpp +++ b/MetadataCrypt.cpp @@ -307,17 +307,11 @@ bool fscrypt_mount_metadata_encrypted(const std::string& blk_device, const std:: // FIXME handle the corrupt case if (needs_encrypt) { 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, - &size_already_done, nr_sec, 0, false); + auto rc = cryptfs_enable_inplace(crypto_blkdev.data(), blk_device.data(), nr_sec, false); if (rc != 0) { LOG(ERROR) << "Inplace crypto failed with code: " << rc; return false; } - if (static_cast(size_already_done) != nr_sec) { - LOG(ERROR) << "Inplace crypto only got up to sector: " << size_already_done; - return false; - } LOG(INFO) << "Inplace encryption complete"; } diff --git a/cryptfs.cpp b/cryptfs.cpp index 8b7ac0a..316c763 100644 --- a/cryptfs.cpp +++ b/cryptfs.cpp @@ -98,9 +98,7 @@ using namespace std::chrono_literals; /* definitions of flags in the structure below */ #define CRYPT_MNT_KEY_UNENCRYPTED 0x1 /* The key for the partition is not encrypted. */ -#define CRYPT_ENCRYPTION_IN_PROGRESS \ - 0x2 /* Encryption partially completed, \ - encrypted_upto valid*/ +#define CRYPT_ENCRYPTION_IN_PROGRESS 0x2 /* no longer used */ #define CRYPT_INCONSISTENT_STATE \ 0x4 /* Set when starting encryption, clear when \ exit cleanly, either through success or \ @@ -195,12 +193,8 @@ struct crypt_mnt_ftr { __le8 N_factor; /* (1 << N) */ __le8 r_factor; /* (1 << r) */ __le8 p_factor; /* (1 << p) */ - __le64 encrypted_upto; /* If we are in state CRYPT_ENCRYPTION_IN_PROGRESS and - we have to stop (e.g. power low) this is the last - 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*/ + __le64 encrypted_upto; /* no longer used */ + __le8 hash_first_block[SHA256_DIGEST_LENGTH]; /* no longer used */ /* key_master key, used to sign the derived key which is then used to generate * the intermediate key @@ -2069,41 +2063,11 @@ static int cryptfs_init_crypt_mnt_ftr(struct crypt_mnt_ftr* ftr) { #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, - const char* real_blkdev, int previously_encrypted_upto) { - off64_t cur_encryption_done = 0, tot_encryption_size = 0; + const char* real_blkdev) { int rc = -1; - /* The size of the userdata partition, and add in the vold volumes below */ - 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); + rc = cryptfs_enable_inplace(crypto_blkdev, real_blkdev, crypt_ftr->fs_size, true); if (rc == ENABLE_INPLACE_ERR_DEV) { /* Hack for b/17898962 */ @@ -2112,10 +2076,8 @@ static int cryptfs_enable_all_volumes(struct crypt_mnt_ftr* crypt_ftr, const cha } 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 * to the round down nature of integer division, so set it here */ 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}; std::string key_loc; int num_vols; - off64_t previously_encrypted_upto = 0; bool rebootEncryption = false; bool onlyCreateHeader = false; std::unique_ptr wakeLock = nullptr; if (get_crypt_ftr_and_key(&crypt_ftr) == 0) { - if (crypt_ftr.flags & CRYPT_ENCRYPTION_IN_PROGRESS) { - /* 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 (crypt_ftr.flags & CRYPT_FORCE_ENCRYPTION) { if (!check_ftr_sha(&crypt_ftr)) { memset(&crypt_ftr, 0, sizeof(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, ""); - if (!strcmp(encrypted_state, "encrypted") && !previously_encrypted_upto) { + if (!strcmp(encrypted_state, "encrypted")) { SLOGE("Device is already running encrypted, aborting"); 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 */ /* Initialize a crypt_mnt_ftr for the partition */ - if (previously_encrypted_upto == 0 && !rebootEncryption) { + if (!rebootEncryption) { if (cryptfs_init_crypt_mnt_ftr(&crypt_ftr)) { 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, CRYPTO_BLOCK_DEVICE, 0); - /* If we are continuing, check checksums match */ - 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; - } - } + rc = cryptfs_enable_all_volumes(&crypt_ftr, crypto_blkdev.c_str(), real_blkdev.data()); /* Undo the dm-crypt mapping whether we succeed or not */ delete_crypto_blk_dev(CRYPTO_BLOCK_DEVICE); @@ -2376,40 +2299,29 @@ int cryptfs_enable_internal(int crypt_type, const char* passwd, int no_ui) { /* Success */ 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); - if (crypt_ftr.encrypted_upto == crypt_ftr.fs_size) { - char value[PROPERTY_VALUE_MAX]; - property_get("ro.crypto.state", value, ""); - if (!strcmp(value, "")) { - /* default encryption - continue first boot sequence */ - property_set("ro.crypto.state", "encrypted"); - property_set("ro.crypto.type", "block"); - wakeLock.reset(nullptr); - if (rebootEncryption && crypt_ftr.crypt_type != CRYPT_TYPE_DEFAULT) { - // Bring up cryptkeeper that will check the password and set it - property_set("vold.decrypt", "trigger_shutdown_framework"); - sleep(2); - property_set("vold.encrypt_progress", ""); - cryptfs_trigger_restart_min_framework(); - } else { - cryptfs_check_passwd(DEFAULT_PASSWORD); - cryptfs_restart_internal(1); - } - return 0; + char value[PROPERTY_VALUE_MAX]; + property_get("ro.crypto.state", value, ""); + if (!strcmp(value, "")) { + /* default encryption - continue first boot sequence */ + property_set("ro.crypto.state", "encrypted"); + property_set("ro.crypto.type", "block"); + wakeLock.reset(nullptr); + if (rebootEncryption && crypt_ftr.crypt_type != CRYPT_TYPE_DEFAULT) { + // Bring up cryptkeeper that will check the password and set it + property_set("vold.decrypt", "trigger_shutdown_framework"); + sleep(2); + property_set("vold.encrypt_progress", ""); + cryptfs_trigger_restart_min_framework(); } else { - sleep(2); /* Give the UI a chance to show 100% progress */ - cryptfs_reboot(RebootType::reboot); + cryptfs_check_passwd(DEFAULT_PASSWORD); + cryptfs_restart_internal(1); } + return 0; } else { - sleep(2); /* Partially encrypted, ensure writes flushed to ssd */ - cryptfs_reboot(RebootType::shutdown); + sleep(2); /* Give the UI a chance to show 100% progress */ + cryptfs_reboot(RebootType::reboot); } } else { char value[PROPERTY_VALUE_MAX];