From 4375f1be4ccdbf78ef4c5ab926d3316503a7b146 Mon Sep 17 00:00:00 2001 From: Wei Wang Date: Fri, 24 Feb 2017 17:43:01 -0800 Subject: [PATCH] Change to use new WaitForProperty API Change to use WaitForProperty API to wait for vold.post_fs_data_done Also change cryptfs to C++ Bug: 35425974 Test: mma, marlin/angler boot Change-Id: Id821f2035788fcc91909f296c83c871c67571de3 --- Android.mk | 2 +- KeyStorage.cpp | 2 +- Keymaster.cpp | 10 ++--- Keymaster.h | 2 +- cryptfs.c => cryptfs.cpp | 84 +++++++++++++++++++--------------------- cryptfs.h | 2 +- 6 files changed, 49 insertions(+), 53 deletions(-) rename cryptfs.c => cryptfs.cpp (98%) diff --git a/Android.mk b/Android.mk index a8982f8..06d98eb 100644 --- a/Android.mk +++ b/Android.mk @@ -17,7 +17,7 @@ common_src_files := \ CheckBattery.cpp \ Ext4Crypt.cpp \ VoldUtil.c \ - cryptfs.c \ + cryptfs.cpp \ Disk.cpp \ VolumeBase.cpp \ PublicVolume.cpp \ diff --git a/KeyStorage.cpp b/KeyStorage.cpp index 9a1304c..34dd6c0 100644 --- a/KeyStorage.cpp +++ b/KeyStorage.cpp @@ -175,7 +175,7 @@ static KeymasterOperation begin(Keymaster& keymaster, const std::string& dir, if (opHandle) { return opHandle; } - if (opHandle.error() != ErrorCode::KEY_REQUIRES_UPGRADE) return opHandle; + if (opHandle.errorCode() != ErrorCode::KEY_REQUIRES_UPGRADE) return opHandle; LOG(DEBUG) << "Upgrading key: " << dir; std::string newKey; if (!keymaster.upgradeKey(kmKey, keyParams, &newKey)) return KeymasterOperation(); diff --git a/Keymaster.cpp b/Keymaster.cpp index 7119dcc..1e1ce66 100644 --- a/Keymaster.cpp +++ b/Keymaster.cpp @@ -278,25 +278,25 @@ int keymaster_sign_object_for_cryptfs_scrypt(const uint8_t* key_blob, while (true) { op = dev.begin(KeyPurpose::SIGN, key, paramBuilder, &outParams); - if (op.error() == ErrorCode::KEY_RATE_LIMIT_EXCEEDED) { + if (op.errorCode() == ErrorCode::KEY_RATE_LIMIT_EXCEEDED) { sleep(ratelimit); continue; } else break; } - if (op.error() != ErrorCode::OK) { - LOG(ERROR) << "Error starting keymaster signature transaction: " << int32_t(op.error()); + if (op.errorCode() != ErrorCode::OK) { + LOG(ERROR) << "Error starting keymaster signature transaction: " << int32_t(op.errorCode()); return -1; } if (!op.updateCompletely(input, &output)) { LOG(ERROR) << "Error sending data to keymaster signature transaction: " - << uint32_t(op.error()); + << uint32_t(op.errorCode()); return -1; } if (!op.finish(&output)) { - LOG(ERROR) << "Error finalizing keymaster signature transaction: " << int32_t(op.error()); + LOG(ERROR) << "Error finalizing keymaster signature transaction: " << int32_t(op.errorCode()); return -1; } diff --git a/Keymaster.h b/Keymaster.h index 7de8700..e47b403 100644 --- a/Keymaster.h +++ b/Keymaster.h @@ -47,7 +47,7 @@ class KeymasterOperation { // Is this instance valid? This is false if creation fails, and becomes // false on finish or if an update fails. explicit operator bool() { return mError == ErrorCode::OK; } - ErrorCode error() { return mError; } + ErrorCode errorCode() { return mError; } // Call "update" repeatedly until all of the input is consumed, and // concatenate the output. Return true on success. bool updateCompletely(const std::string& input, std::string* output); diff --git a/cryptfs.c b/cryptfs.cpp similarity index 98% rename from cryptfs.c rename to cryptfs.cpp index 067c025..f2f0f18 100644 --- a/cryptfs.c +++ b/cryptfs.cpp @@ -56,14 +56,16 @@ #include "ScryptParameters.h" #include "VolumeManager.h" #include "VoldUtil.h" -#include "crypto_scrypt.h" #include "Ext4Crypt.h" #include "f2fs_sparseblock.h" #include "CheckBattery.h" #include "Process.h" #include "Keymaster.h" - +#include "android-base/properties.h" #include +extern "C" { +#include +} #define UNUSED __attribute__((unused)) @@ -94,8 +96,6 @@ #define RETRY_MOUNT_ATTEMPTS 10 #define RETRY_MOUNT_DELAY_SECONDS 1 -char *me = "cryptfs"; - static unsigned char saved_master_key[KEY_LEN_BYTES]; static char *saved_mount_point; static int master_key_saved = 0; @@ -162,7 +162,7 @@ static int keymaster_sign_object(struct crypt_mnt_ftr *ftr, // object size. However, it's still broken (but not unusably // so) because we really should be using a proper deterministic // RSA padding function, such as PKCS1. - memcpy(to_sign + 1, object, min(RSA_KEY_SIZE_BYTES - 1, object_size)); + memcpy(to_sign + 1, object, std::min((size_t)RSA_KEY_SIZE_BYTES - 1, object_size)); SLOGI("Signing safely-padded object"); break; default: @@ -447,7 +447,7 @@ static void upgrade_crypt_ftr(int fd, struct crypt_mnt_ftr *crypt_ftr, off64_t o SLOGW("upgrading crypto footer to 1.1"); - pdata = malloc(CRYPT_PERSIST_DATA_SIZE); + pdata = (crypt_persist_data *)malloc(CRYPT_PERSIST_DATA_SIZE); if (pdata == NULL) { SLOGE("Cannot allocate persisent data\n"); return; @@ -615,7 +615,7 @@ static int load_persistent_data(void) /* If not encrypted, just allocate an empty table and initialize it */ property_get("ro.crypto.state", encrypted_state, ""); if (strcmp(encrypted_state, "encrypted") ) { - pdata = malloc(CRYPT_PERSIST_DATA_SIZE); + pdata = (crypt_persist_data*)malloc(CRYPT_PERSIST_DATA_SIZE); if (pdata) { init_empty_persist_data(pdata, CRYPT_PERSIST_DATA_SIZE); persist_data = pdata; @@ -649,7 +649,7 @@ static int load_persistent_data(void) return -1; } - pdata = malloc(crypt_ftr.persist_data_size); + pdata = (crypt_persist_data*)malloc(crypt_ftr.persist_data_size); if (pdata == NULL) { SLOGE("Cannot allocate memory for persistent data"); goto err; @@ -728,7 +728,7 @@ static int save_persistent_data(void) return -1; } - pdata = malloc(crypt_ftr.persist_data_size); + pdata = (crypt_persist_data*)malloc(crypt_ftr.persist_data_size); if (pdata == NULL) { SLOGE("Cannot allocate persistant data"); goto err; @@ -817,7 +817,7 @@ static void convert_key_to_hex_ascii(const unsigned char *master_key, static int load_crypto_mapping_table(struct crypt_mnt_ftr *crypt_ftr, const unsigned char *master_key, const char *real_blk_name, const char *name, int fd, const char *extra_params) { - _Alignas(struct dm_ioctl) char buffer[DM_CRYPT_BUF_SIZE]; + alignas(struct dm_ioctl) char buffer[DM_CRYPT_BUF_SIZE]; struct dm_ioctl *io; struct dm_target_spec *tgt; char *crypt_params; @@ -906,7 +906,7 @@ static int create_crypto_blk_dev(struct crypt_mnt_ftr *crypt_ftr, int err; int retval = -1; int version[3]; - char *extra_params; + const char *extra_params; int load_count; if ((fd = open("/dev/device-mapper", O_RDWR|O_CLOEXEC)) < 0 ) { @@ -968,7 +968,7 @@ errout: return retval; } -static int delete_crypto_blk_dev(char *name) +static int delete_crypto_blk_dev(const char *name) { int fd; char buffer[DM_CRYPT_BUF_SIZE]; @@ -1240,7 +1240,7 @@ static int decrypt_master_key(const char *passwd, unsigned char *decrypted_maste return ret; } -static int create_encrypted_random_key(char *passwd, unsigned char *master_key, unsigned char *salt, +static int create_encrypted_random_key(const char *passwd, unsigned char *master_key, unsigned char *salt, struct crypt_mnt_ftr *crypt_ftr) { int fd; unsigned char key_buf[KEY_LEN_BYTES]; @@ -1301,7 +1301,6 @@ int wait_and_unmount(const char *mountpoint, bool kill) return rc; } -#define DATA_PREP_TIMEOUT 1000 static int prep_data_fs(void) { int i; @@ -1315,17 +1314,9 @@ static int prep_data_fs(void) SLOGD("Just triggered post_fs_data\n"); /* Wait a max of 50 seconds, hopefully it takes much less */ - for (i=0; iN_factor; + int r = 1 << crypt_ftr->r_factor; + int p = 1 << crypt_ftr->p_factor; SLOGD("crypt_ftr->fs_size = %lld\n", crypt_ftr->fs_size); orig_failed_decrypt_count = crypt_ftr->failed_decrypt_count; @@ -1612,9 +1606,6 @@ static int test_mount_encrypted_fs(struct crypt_mnt_ftr* crypt_ftr, /* Work out if the problem is the password or the data */ unsigned char scrypted_intermediate_key[sizeof(crypt_ftr-> scrypted_intermediate_key)]; - int N = 1 << crypt_ftr->N_factor; - int r = 1 << crypt_ftr->r_factor; - int p = 1 << crypt_ftr->p_factor; rc = crypto_scrypt(intermediate_key, intermediate_key_size, crypt_ftr->salt, sizeof(crypt_ftr->salt), @@ -1771,7 +1762,7 @@ int check_unmounted_and_get_ftr(struct crypt_mnt_ftr* crypt_ftr) return 0; } -int cryptfs_check_passwd(char *passwd) +int cryptfs_check_passwd(const char *passwd) { SLOGI("cryptfs_check_passwd"); if (e4crypt_is_native()) { @@ -2125,13 +2116,13 @@ static int encrypt_groups(struct encryptGroupsData* data) off64_t ret; int rc = -1; - data->buffer = malloc(info.block_size * BLOCKS_AT_A_TIME); + data->buffer = (char *)malloc(info.block_size * BLOCKS_AT_A_TIME); if (!data->buffer) { SLOGE("Failed to allocate crypto buffer"); goto errout; } - block_bitmap = malloc(info.block_size); + block_bitmap = (u8 *)malloc(info.block_size); if (!block_bitmap) { SLOGE("failed to allocate block bitmap"); goto errout; @@ -2141,8 +2132,8 @@ static int encrypt_groups(struct encryptGroupsData* data) SLOGI("Encrypting group %d", i); u32 first_block = aux_info.first_data_block + i * info.blocks_per_group; - u32 block_count = min(info.blocks_per_group, - aux_info.len_blocks - first_block); + u32 block_count = std::min(info.blocks_per_group, + (u32)(aux_info.len_blocks - first_block)); off64_t offset = (u64)info.block_size * aux_info.bg_desc[i].bg_block_bitmap; @@ -2214,6 +2205,8 @@ static int cryptfs_enable_inplace_ext4(char *crypto_blkdev, u32 i; struct encryptGroupsData data; int rc; // Can't initialize without causing warning -Wclobbered + struct timespec time_started = {0}; + int retries = RETRY_MOUNT_ATTEMPTS; if (previously_encrypted_upto > *size_already_done) { SLOGD("Not fast encrypting since resuming part way through"); @@ -2232,7 +2225,6 @@ static int cryptfs_enable_inplace_ext4(char *crypto_blkdev, } // Wait until the block device appears. Re-use the mount retry values since it is reasonable. - int retries = RETRY_MOUNT_ATTEMPTS; while ((data.cryptofd = open(crypto_blkdev, O_WRONLY|O_CLOEXEC)) < 0) { if (--retries) { SLOGE("Error opening crypto_blkdev %s for ext4 inplace encrypt. err=%d(%s), retrying\n", @@ -2272,7 +2264,6 @@ static int cryptfs_enable_inplace_ext4(char *crypto_blkdev, data.one_pct = data.tot_used_blocks / 100; data.cur_pct = 0; - struct timespec time_started = {0}; if (clock_gettime(CLOCK_MONOTONIC, &time_started)) { SLOGW("Error getting time at start"); // Note - continue anyway - we'll run with 0 @@ -2390,7 +2381,7 @@ static int cryptfs_enable_inplace_f2fs(char *crypto_blkdev, data.time_started = time(NULL); data.remaining_time = -1; - data.buffer = malloc(f2fs_info->block_size); + data.buffer = (char *)malloc(f2fs_info->block_size); if (!data.buffer) { SLOGE("Failed to allocate crypto buffer"); goto errout; @@ -2686,7 +2677,7 @@ static int cryptfs_enable_all_volumes(struct crypt_mnt_ftr *crypt_ftr, int how, return rc; } -int cryptfs_enable_internal(char *howarg, int crypt_type, char *passwd, +int cryptfs_enable_internal(char *howarg, int crypt_type, const char *passwd, int no_ui) { int how = 0; @@ -2701,6 +2692,8 @@ int cryptfs_enable_internal(char *howarg, int crypt_type, char *passwd, int num_vols; off64_t previously_encrypted_upto = 0; bool rebootEncryption = false; + bool onlyCreateHeader = false; + int fd = -1; if (!strcmp(howarg, "wipe")) { how = CRYPTO_ENABLE_WIPE; @@ -2751,7 +2744,7 @@ int cryptfs_enable_internal(char *howarg, int crypt_type, char *passwd, fs_mgr_get_crypt_info(fstab, 0, real_blkdev, sizeof(real_blkdev)); /* Get the size of the real block device */ - int fd = open(real_blkdev, O_RDONLY|O_CLOEXEC); + fd = open(real_blkdev, O_RDONLY|O_CLOEXEC); if (fd == -1) { SLOGE("Cannot open block device %s\n", real_blkdev); goto error_unencrypted; @@ -2800,7 +2793,6 @@ int cryptfs_enable_internal(char *howarg, int crypt_type, char *passwd, /* no_ui means we are being called from init, not settings. Now we always reboot from settings, so !no_ui means reboot */ - bool onlyCreateHeader = false; if (!no_ui) { /* Try fallback, which is to reboot and try there */ onlyCreateHeader = true; @@ -2886,7 +2878,7 @@ int cryptfs_enable_internal(char *howarg, int crypt_type, char *passwd, * If none, create a valid empty table and save that. */ if (!persist_data) { - pdata = malloc(CRYPT_PERSIST_DATA_SIZE); + pdata = (crypt_persist_data *)malloc(CRYPT_PERSIST_DATA_SIZE); if (pdata) { init_empty_persist_data(pdata, CRYPT_PERSIST_DATA_SIZE); persist_data = pdata; @@ -2999,8 +2991,12 @@ int cryptfs_enable_internal(char *howarg, int crypt_type, char *passwd, if (!strcmp(value, "1")) { /* wipe data if encryption failed */ SLOGE("encryption failed - rebooting into recovery to wipe data\n"); - if (!write_bootloader_message("--wipe_data\n--reason=cryptfs_enable_internal\n")) { - SLOGE("could not write bootloader message\n"); + std::string err; + const std::vector options = { + "--wipe_data\n--reason=cryptfs_enable_internal\n" + }; + if (!write_bootloader_message(options, &err)) { + SLOGE("could not write bootloader message: %s", err.c_str()); } cryptfs_reboot(recovery); } else { diff --git a/cryptfs.h b/cryptfs.h index 5c05001..352a576 100644 --- a/cryptfs.h +++ b/cryptfs.h @@ -228,7 +228,7 @@ extern "C" { unsigned char *ikey, void *params); int cryptfs_crypto_complete(void); - int cryptfs_check_passwd(char *pw); + int cryptfs_check_passwd(const char *pw); int cryptfs_verify_passwd(char *newpw); int cryptfs_restart(void); int cryptfs_enable(char *flag, int type, char *passwd, int no_ui);