diff --git a/Android.bp b/Android.bp index 26c4745..423100c 100644 --- a/Android.bp +++ b/Android.bp @@ -166,6 +166,9 @@ cc_library_static { header_libs: ["libcryptfs_hw_headers"], shared_libs: ["libcryptfs_hw"], }, + device_support_hwfde_perf: { + cflags: ["-DCONFIG_HW_DISK_ENCRYPT_PERF"], + }, }, shared_libs: [ "android.hardware.health.storage@1.0", diff --git a/EncryptInplace.cpp b/EncryptInplace.cpp index b1bd11d..73dce17 100644 --- a/EncryptInplace.cpp +++ b/EncryptInplace.cpp @@ -32,6 +32,9 @@ #include #include +#ifdef CONFIG_HW_DISK_ENCRYPTION +#include "cryptfs_hw.h" +#endif // HORRIBLE HACK, FIXME #include "cryptfs.h" @@ -280,6 +283,27 @@ static int cryptfs_enable_inplace_ext4(const char* crypto_blkdev, const char* re } LOG(DEBUG) << "Opening" << crypto_blkdev; +#if defined(CONFIG_HW_DISK_ENCRYPTION) && defined(CONFIG_HW_DISK_ENCRYPT_PERF) + if (is_ice_enabled()) + data.cryptofd = data.realfd; + else { + // Wait until the block device appears. Re-use the mount retry values since it is reasonable. + while ((data.cryptofd = open(crypto_blkdev, O_WRONLY|O_CLOEXEC)) < 0) { + if (--retries) { + PLOG(ERROR) << "Error opening crypto_blkdev " << crypto_blkdev + << " for ext4 inplace encrypt. err=" << errno + << "(" << strerror(errno) << "), retrying"; + sleep(RETRY_MOUNT_DELAY_SECONDS); + } else { + PLOG(ERROR) << "Error opening crypto_blkdev " << crypto_blkdev + << " for ext4 inplace encrypt. err=" << errno + << "(" << strerror(errno) << "), retrying"; + rc = ENABLE_INPLACE_ERR_DEV; + goto errout; + } + } + } +#else // Wait until the block device appears. Re-use the mount retry values since it is reasonable. while ((data.cryptofd = open(crypto_blkdev, O_WRONLY | O_CLOEXEC)) < 0) { if (--retries) { @@ -293,6 +317,7 @@ static int cryptfs_enable_inplace_ext4(const char* crypto_blkdev, const char* re goto errout; } } +#endif if (setjmp(setjmp_env)) { // NOLINT LOG(ERROR) << "Reading ext4 extent caused an exception"; @@ -338,7 +363,12 @@ static int cryptfs_enable_inplace_ext4(const char* crypto_blkdev, const char* re errout: close(data.realfd); +#if defined(CONFIG_HW_DISK_ENCRYPTION) && defined(CONFIG_HW_DISK_ENCRYPT_PERF) + if (!is_ice_enabled()) + close(data.cryptofd); +#else close(data.cryptofd); +#endif return rc; } @@ -414,12 +444,26 @@ static int cryptfs_enable_inplace_f2fs(const char* crypto_blkdev, const char* re PLOG(ERROR) << "Error opening real_blkdev " << real_blkdev << " for f2fs inplace encrypt"; goto errout; } +#if defined(CONFIG_HW_DISK_ENCRYPTION) && defined(CONFIG_HW_DISK_ENCRYPT_PERF) + if (is_ice_enabled()) + data.cryptofd = data.realfd; + else { + if ((data.cryptofd = open64(crypto_blkdev, O_WRONLY|O_CLOEXEC)) < 0) { + PLOG(ERROR) << "Error opening crypto_blkdev " << crypto_blkdev + << " for f2fs inplace encrypt. err=" << errno + << "(" << strerror(errno) << "), retrying"; + rc = ENABLE_INPLACE_ERR_DEV; + goto errout; + } + } +#else if ((data.cryptofd = open64(crypto_blkdev, O_WRONLY | O_CLOEXEC)) < 0) { PLOG(ERROR) << "Error opening crypto_blkdev " << crypto_blkdev << " for f2fs inplace encrypt"; rc = ENABLE_INPLACE_ERR_DEV; goto errout; } +#endif f2fs_info = generate_f2fs_info(data.realfd); if (!f2fs_info) goto errout; @@ -467,7 +511,12 @@ errout: free(f2fs_info); free(data.buffer); close(data.realfd); +#if defined(CONFIG_HW_DISK_ENCRYPTION) && defined(CONFIG_HW_DISK_ENCRYPT_PERF) + if (!is_ice_enabled()) + close(data.cryptofd); +#else close(data.cryptofd); +#endif return rc; } @@ -488,11 +537,25 @@ static int cryptfs_enable_inplace_full(const char* crypto_blkdev, const char* re return ENABLE_INPLACE_ERR_OTHER; } +#if defined(CONFIG_HW_DISK_ENCRYPTION) && defined(CONFIG_HW_DISK_ENCRYPT_PERF) + if (is_ice_enabled()) + cryptofd = realfd; + else { + if ((cryptofd = open(crypto_blkdev, O_WRONLY|O_CLOEXEC)) < 0) { + PLOG(ERROR) << "Error opening crypto_blkdev " << crypto_blkdev + << " for inplace encrypt. err=" << errno + << "(" << strerror(errno) << "), retrying"; + close(realfd); + return ENABLE_INPLACE_ERR_DEV; + } + } +#else if ((cryptofd = open(crypto_blkdev, O_WRONLY | O_CLOEXEC)) < 0) { PLOG(ERROR) << "Error opening crypto_blkdev " << crypto_blkdev << " for inplace encrypt"; close(realfd); return ENABLE_INPLACE_ERR_DEV; } +#endif /* This is pretty much a simple loop of reading 4K, and writing 4K. * The size passed in is the number of 512 byte sectors in the filesystem. @@ -513,10 +576,19 @@ static int cryptfs_enable_inplace_full(const char* crypto_blkdev, const char* re goto errout; } +#if defined(CONFIG_HW_DISK_ENCRYPTION) && defined(CONFIG_HW_DISK_ENCRYPT_PERF) + if (!is_ice_enabled()) { + if (lseek64(cryptofd, i * CRYPT_SECTOR_SIZE, SEEK_SET) < 0) { + PLOG(ERROR) << "Cannot seek to previously encrypted point on " << crypto_blkdev; + goto errout; + } + } +#else if (lseek64(cryptofd, i * CRYPT_SECTOR_SIZE, SEEK_SET) < 0) { PLOG(ERROR) << "Cannot seek to previously encrypted point on " << crypto_blkdev; goto errout; } +#endif for (; i < size && i % CRYPT_SECTORS_PER_BUFSIZE != 0; ++i) { if (unix_read(realfd, buf, CRYPT_SECTOR_SIZE) <= 0) { @@ -579,7 +651,12 @@ static int cryptfs_enable_inplace_full(const char* crypto_blkdev, const char* re errout: close(realfd); +#if defined(CONFIG_HW_DISK_ENCRYPTION) && defined(CONFIG_HW_DISK_ENCRYPT_PERF) + if (!is_ice_enabled()) + close(cryptofd); +#else close(cryptofd); +#endif return rc; } diff --git a/VoldUtil.h b/VoldUtil.h index e0945bf..8c06236 100644 --- a/VoldUtil.h +++ b/VoldUtil.h @@ -22,3 +22,7 @@ extern android::fs_mgr::Fstab fstab_default; #define DATA_MNT_POINT "/data" #define METADATA_MNT_POINT "/metadata" + +#ifdef CONFIG_HW_DISK_ENCRYPT_PERF +void get_blkdev_start_sector(int fd, unsigned long* st_sec); +#endif diff --git a/cryptfs.cpp b/cryptfs.cpp index b6dd5f3..3592a38 100644 --- a/cryptfs.cpp +++ b/cryptfs.cpp @@ -1684,6 +1684,9 @@ static void cryptfs_trigger_restart_min_framework() { /* returns < 0 on failure */ static int cryptfs_restart_internal(int restart_main) { char crypto_blkdev[MAXPATHLEN]; +#ifdef CONFIG_HW_DISK_ENCRYPTION + char blkdev[MAXPATHLEN]; +#endif int rc = -1; static int restart_successful = 0; @@ -1742,6 +1745,24 @@ static int cryptfs_restart_internal(int restart_main) { * the tmpfs filesystem, and mount the real one. */ +#if defined(CONFIG_HW_DISK_ENCRYPTION) +#if defined(CONFIG_HW_DISK_ENCRYPT_PERF) + if (is_ice_enabled()) { + fs_mgr_get_crypt_info(fstab_default, 0, blkdev, sizeof(blkdev)); + if (set_ice_param(START_ENCDEC)) { + SLOGE("Failed to set ICE data"); + return -1; + } + } +#else + property_get("ro.crypto.fs_crypto_blkdev", blkdev, ""); + if (strlen(blkdev) == 0) { + SLOGE("fs_crypto_blkdev not set\n"); + return -1; + } + if (!(rc = wait_and_unmount(DATA_MNT_POINT, true))) { +#endif +#else property_get("ro.crypto.fs_crypto_blkdev", crypto_blkdev, ""); if (strlen(crypto_blkdev) == 0) { SLOGE("fs_crypto_blkdev not set\n"); @@ -1749,6 +1770,7 @@ static int cryptfs_restart_internal(int restart_main) { } if (!(rc = wait_and_unmount(DATA_MNT_POINT, true))) { +#endif /* If ro.crypto.readonly is set to 1, mount the decrypted * filesystem readonly. This is used when /data is mounted by * recovery mode. @@ -1775,13 +1797,22 @@ 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, +#ifdef CONFIG_HW_DISK_ENCRYPTION + while ((mount_rc = fs_mgr_do_mount(&fstab_default, DATA_MNT_POINT, blkdev.data(), 0, needs_cp, false)) != 0) { +#else + while ((mount_rc = fs_mgr_do_mount(&fstab_default, DATA_MNT_POINT, crypto_blkdev.data(), 0, + needs_cp, false)) != 0) { +#endif if (mount_rc == FS_MGR_DOMNT_BUSY) { /* TODO: invoke something similar to Process::killProcessWithOpenFiles(DATA_MNT_POINT, retries > RETRY_MOUNT_ATTEMPT/2 ? 1 : 2 ) */ +#ifdef CONFIG_HW_DISK_ENCRYPTION + SLOGI("Failed to mount %s because it is busy - waiting", blkdev); +#else SLOGI("Failed to mount %s because it is busy - waiting", crypto_blkdev); +#endif if (--retries) { sleep(RETRY_MOUNT_DELAY_SECONDS); } else { @@ -1827,7 +1858,9 @@ static int cryptfs_restart_internal(int restart_main) { /* Give it a few moments to get started */ sleep(1); +#ifndef CONFIG_HW_DISK_ENCRYPT_PERF } +#endif if (rc == 0) { restart_successful = 1; @@ -1927,12 +1960,14 @@ static int test_mount_hw_encrypted_fs(struct crypt_mnt_ftr* crypt_ftr, } else { if (is_ice_enabled()) { +#ifndef CONFIG_HW_DISK_ENCRYPT_PERF if (create_crypto_blk_dev(crypt_ftr, (unsigned char*)&key_index, real_blkdev, crypto_blkdev, label, 0)) { SLOGE("Error creating decrypted block device"); rc = -1; goto errout; } +#endif } else { if (create_crypto_blk_dev(crypt_ftr, decrypted_master_key, real_blkdev, crypto_blkdev, label, 0)) { @@ -1952,6 +1987,9 @@ static int test_mount_hw_encrypted_fs(struct crypt_mnt_ftr* crypt_ftr, /* Save the name of the crypto block device * so we can mount it when restarting the framework. */ +#ifdef CONFIG_HW_DISK_ENCRYPT_PERF + if (!is_ice_enabled()) +#endif property_set("ro.crypto.fs_crypto_blkdev", crypto_blkdev); master_key_saved = 1; } @@ -2702,8 +2740,12 @@ int cryptfs_enable_internal(int crypt_type, const char* passwd, int no_ui) { decrypt_master_key(passwd, decrypted_master_key, &crypt_ftr, 0, 0); #ifdef CONFIG_HW_DISK_ENCRYPTION if (is_hw_disk_encryption((char*)crypt_ftr.crypto_type_name) && is_ice_enabled()) - create_crypto_blk_dev(&crypt_ftr, (unsigned char*)&key_index, real_blkdev.c_str(), &crypto_blkdev, +#ifdef CONFIG_HW_DISK_ENCRYPT_PERF + crypto_blkdev = real_blkdev; +#else + create_crypto_blk_dev(&crypt_ftr, (unsigned char*)&key_index, real_blkdev.c_str(), crypto_blkdev, CRYPTO_BLOCK_DEVICE, 0); +#endif else create_crypto_blk_dev(&crypt_ftr, decrypted_master_key, real_blkdev.c_str(), &crypto_blkdev, CRYPTO_BLOCK_DEVICE, 0); @@ -2716,6 +2758,12 @@ int cryptfs_enable_internal(int crypt_type, const char* passwd, int no_ui) { rc = 0; if (previously_encrypted_upto) { __le8 hash_first_block[SHA256_DIGEST_LENGTH]; +#if defined(CONFIG_HW_DISK_ENCRYPTION) && defined(CONFIG_HW_DISK_ENCRYPT_PERF) + if (set_ice_param(START_ENCDEC)) { + SLOGE("Failed to set ICE data"); + goto error_shutting_down; + } +#endif rc = cryptfs_SHA256_fileblock(crypto_blkdev.c_str(), hash_first_block); if (!rc && @@ -2725,11 +2773,23 @@ int cryptfs_enable_internal(int crypt_type, const char* passwd, int no_ui) { } } +#if defined(CONFIG_HW_DISK_ENCRYPTION) && defined(CONFIG_HW_DISK_ENCRYPT_PERF) + if (set_ice_param(START_ENC)) { + SLOGE("Failed to set ICE data"); + goto error_shutting_down; + } +#endif if (!rc) { rc = cryptfs_enable_all_volumes(&crypt_ftr, crypto_blkdev.c_str(), real_blkdev.data(), previously_encrypted_upto); } +#if defined(CONFIG_HW_DISK_ENCRYPTION) && defined(CONFIG_HW_DISK_ENCRYPT_PERF) + if (set_ice_param(START_ENCDEC)) { + SLOGE("Failed to set ICE data"); + goto error_shutting_down; + } +#endif /* 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); @@ -2740,7 +2800,12 @@ int cryptfs_enable_internal(int crypt_type, const char* passwd, int no_ui) { } /* Undo the dm-crypt mapping whether we succeed or not */ +#if defined(CONFIG_HW_DISK_ENCRYPTION) && defined(CONFIG_HW_DISK_ENCRYPT_PERF) + if (!is_ice_enabled()) + delete_crypto_blk_dev(CRYPTO_BLOCK_DEVICE); +#else delete_crypto_blk_dev(CRYPTO_BLOCK_DEVICE); +#endif if (!rc) { /* Success */