From c657cc00374f2dc397e60cd249d64f745edb056d Mon Sep 17 00:00:00 2001 From: Dees Troy Date: Fri, 16 Jan 2015 22:48:47 +0000 Subject: Support Qualcomm hardware decrypt Change-Id: I121ef0f5da209be48f6d87559d539c7fc6d85336 --- crypto/lollipop/Android.mk | 27 ++++++++++ crypto/lollipop/cryptfs.c | 129 ++++++++++++++++++++++++++++++++++++++++----- crypto/lollipop/main.c | 35 ++++++++++++ partition.cpp | 1 + prebuilt/Android.mk | 3 ++ 5 files changed, 181 insertions(+), 14 deletions(-) create mode 100644 crypto/lollipop/main.c diff --git a/crypto/lollipop/Android.mk b/crypto/lollipop/Android.mk index 148e328da..938e0d184 100644 --- a/crypto/lollipop/Android.mk +++ b/crypto/lollipop/Android.mk @@ -8,8 +8,35 @@ LOCAL_CFLAGS := LOCAL_SRC_FILES = cryptfs.c LOCAL_SHARED_LIBRARIES := libcrypto libhardware libcutils LOCAL_C_INCLUDES := external/openssl/include $(commands_recovery_local_path)/crypto/scrypt/lib/crypto + +ifeq ($(TARGET_HW_DISK_ENCRYPTION),true) + LOCAL_C_INCLUDES += device/qcom/common/cryptfs_hw + LOCAL_SHARED_LIBRARIES += libcryptfs_hw + LOCAL_CFLAGS += -DCONFIG_HW_DISK_ENCRYPTION +endif + LOCAL_WHOLE_STATIC_LIBRARIES += libscrypttwrp_static include $(BUILD_SHARED_LIBRARY) + + +#include $(CLEAR_VARS) +#LOCAL_MODULE := twrpdec +#LOCAL_MODULE_TAGS := eng optional +#LOCAL_MODULE_CLASS := RECOVERY_EXECUTABLES +#LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/sbin +#LOCAL_SRC_FILES := main.c cryptfs.c +#LOCAL_SHARED_LIBRARIES := libcrypto libhardware libcutils libc +#LOCAL_C_INCLUDES := external/openssl/include $(commands_recovery_local_path)/crypto/scrypt/lib/crypto + +#ifeq ($(TARGET_HW_DISK_ENCRYPTION),true) +# LOCAL_C_INCLUDES += device/qcom/common/cryptfs_hw +# LOCAL_SHARED_LIBRARIES += libcryptfs_hw +# LOCAL_CFLAGS += -DCONFIG_HW_DISK_ENCRYPTION +#endif + +#LOCAL_WHOLE_STATIC_LIBRARIES += libscrypttwrp_static +#include $(BUILD_EXECUTABLE) + endif diff --git a/crypto/lollipop/cryptfs.c b/crypto/lollipop/cryptfs.c index 496b960ad..697593fd7 100644 --- a/crypto/lollipop/cryptfs.c +++ b/crypto/lollipop/cryptfs.c @@ -21,6 +21,7 @@ */ #include +#include #include #include #include @@ -52,6 +53,10 @@ #define UNUSED __attribute__((unused)) +#ifdef CONFIG_HW_DISK_ENCRYPTION +#include "cryptfs_hw.h" +#endif + #define DM_CRYPT_BUF_SIZE 4096 #define HASH_COUNT 2000 @@ -592,12 +597,26 @@ static int load_crypto_mapping_table(struct crypt_mnt_ftr *crypt_ftr, unsigned c tgt->status = 0; tgt->sector_start = 0; tgt->length = crypt_ftr->fs_size; +#ifdef CONFIG_HW_DISK_ENCRYPTION + if(is_hw_disk_encryption((char*)crypt_ftr->crypto_type_name) && is_hw_fde_enabled()) { + printf("load_crypto_mapping_table using req-crypt\n"); + strlcpy(tgt->target_type, "req-crypt",DM_MAX_TYPE_NAME); + } else { + printf("load_crypto_mapping_table using crypt\n"); + strlcpy(tgt->target_type, "crypt", DM_MAX_TYPE_NAME); + } +#else strcpy(tgt->target_type, "crypt"); +#endif crypt_params = buffer + sizeof(struct dm_ioctl) + sizeof(struct dm_target_spec); convert_key_to_hex_ascii(master_key, crypt_ftr->keysize, master_key_ascii); sprintf(crypt_params, "%s %s 0 %s 0 %s", crypt_ftr->crypto_type_name, master_key_ascii, real_blk_name, extra_params); + + printf("%s: target_type = %s\n", __func__, tgt->target_type); + printf("%s: real_blk_name = %s, extra_params = %s\n", __func__, real_blk_name, extra_params); + crypt_params += strlen(crypt_params) + 1; crypt_params = (char *) (((unsigned long)crypt_params + 7) & ~8); /* Align to an 8 byte boundary */ tgt->next = crypt_params - buffer; @@ -623,6 +642,7 @@ static int get_dm_crypt_version(int fd, const char *name, int *version) char buffer[DM_CRYPT_BUF_SIZE]; struct dm_ioctl *io; struct dm_target_versions *v; + int flag; int i; io = (struct dm_ioctl *) buffer; @@ -638,7 +658,17 @@ static int get_dm_crypt_version(int fd, const char *name, int *version) */ v = (struct dm_target_versions *) &buffer[sizeof(struct dm_ioctl)]; while (v->next) { +#ifdef CONFIG_HW_DISK_ENCRYPTION + if (is_hw_fde_enabled()) { + flag = (!strcmp(v->name, "crypt") || !strcmp(v->name, "req-crypt")); + } else { + flag = (!strcmp(v->name, "crypt")); + } + printf("get_dm_crypt_version flag: %i, name: '%s'\n", flag, v->name); + if (flag) { +#else if (! strcmp(v->name, "crypt")) { +#endif /* We found the crypt driver, return the version, and get out */ version[0] = v->version[0]; version[1] = v->version[1]; @@ -660,12 +690,16 @@ static int create_crypto_blk_dev(struct crypt_mnt_ftr *crypt_ftr, unsigned char struct dm_ioctl *io; struct dm_target_spec *tgt; unsigned int minor; - int fd; + int fd=0; int i; int retval = -1; int version[3]; char *extra_params; int load_count; +#ifdef CONFIG_HW_DISK_ENCRYPTION + char encrypted_state[PROPERTY_VALUE_MAX] = {0}; + char progress[PROPERTY_VALUE_MAX] = {0}; +#endif if ((fd = open("/dev/device-mapper", O_RDWR)) < 0 ) { printf("Cannot open device-mapper\n"); @@ -689,6 +723,31 @@ static int create_crypto_blk_dev(struct crypt_mnt_ftr *crypt_ftr, unsigned char minor = (io->dev & 0xff) | ((io->dev >> 12) & 0xfff00); snprintf(crypto_blk_name, MAXPATHLEN, "/dev/block/dm-%u", minor); +#ifdef CONFIG_HW_DISK_ENCRYPTION + if (is_hw_fde_enabled() && is_hw_disk_encryption((char*) crypt_ftr->crypto_type_name)) { + /* Set fde_enabled if either FDE completed or in-progress */ + property_get("ro.crypto.state", encrypted_state, ""); /* FDE completed */ + property_get("vold.encrypt_progress", progress, ""); /* FDE in progress */ + if (!strcmp(encrypted_state, "encrypted") || strcmp(progress, "")) { + extra_params = "fde_enabled"; + printf("create_crypto_blk_dev extra_params set to fde_enabled\n"); + } else { + extra_params = "fde_disabled"; + printf("create_crypto_blk_dev extra_params set to fde_disabled\n"); + } + } else { + extra_params = ""; + printf("create_crypto_blk_dev extra_params set to empty string\n"); + if (!get_dm_crypt_version(fd, name, version)) { + /* Support for allow_discards was added in version 1.11.0 */ + if ((version[0] >= 2) || + ((version[0] == 1) && (version[1] >= 11))) { + extra_params = "1 allow_discards"; + printf("Enabling support for allow_discards in dmcrypt.\n"); + } + } + } +#else extra_params = ""; if (! get_dm_crypt_version(fd, name, version)) { /* Support for allow_discards was added in version 1.11.0 */ @@ -698,6 +757,7 @@ static int create_crypto_blk_dev(struct crypt_mnt_ftr *crypt_ftr, unsigned char printf("Enabling support for allow_discards in dmcrypt.\n"); } } +#endif load_count = load_crypto_mapping_table(crypt_ftr, master_key, real_blk_name, name, fd, extra_params); @@ -1020,7 +1080,7 @@ static int test_mount_encrypted_fs(struct crypt_mnt_ftr* crypt_ftr, char crypto_blkdev[MAXPATHLEN]; char tmp_mount_point[64]; unsigned int orig_failed_decrypt_count; - int rc; + int rc = 0; kdf_func kdf; void *kdf_params; int use_keymaster = 0; @@ -1040,6 +1100,18 @@ static int test_mount_encrypted_fs(struct crypt_mnt_ftr* crypt_ftr, } } +#ifdef CONFIG_HW_DISK_ENCRYPTION + if (is_hw_fde_enabled()) { + if(is_hw_disk_encryption((char*) crypt_ftr->crypto_type_name)) { + if (!set_hw_device_encryption_key(passwd, (char*) crypt_ftr->crypto_type_name)) { + rc = -1; + printf("Failed to set_hw_device_encryption_key\n"); + goto errout; + } + } + } +#endif + // Create crypto block device - all (non fatal) code paths // need it if (create_crypto_blk_dev(crypt_ftr, decrypted_master_key, @@ -1207,7 +1279,7 @@ char* adjust_passwd(const char* passwd) // an even length, since each character encodes to two characters. length = strlen(passwd); if (length % 2) { - printf("Password not correctly hex encoded."); + printf("Password not correctly hex encoded.\n"); return 0; } @@ -1241,10 +1313,10 @@ char* adjust_passwd(const char* passwd) * regular character codes to their hexadecimal representation to make * decrypt work properly with Android 5.0 lollipop decryption. */ -char* hexadj_passwd(const char* passwd) +char* hexadj_passwd(const char* passwd, int has_hw_crypto) { size_t index, length; - char* ptr = passwd; + const char* ptr = passwd; if (!passwd) { return 0; @@ -1261,7 +1333,15 @@ char* hexadj_passwd(const char* passwd) sprintf(hex + (index * 2), "%02X", *ptr); ptr++; } - +#ifdef CONFIG_HW_DISK_ENCRYPTION + if (has_hw_crypto) { + printf("hexadj_passwd converting to lower case for hardware disk crypto.\n"); + length *= 2; + for (index = 0; index < length; index++) { + hex[index] = tolower(hex[index]); + } + } +#endif return hex; } @@ -1279,22 +1359,36 @@ int cryptfs_check_passwd(char *passwd) { struct crypt_mnt_ftr crypt_ftr; int rc; + int has_hw_crypto = 0; rc = check_unmounted_and_get_ftr(&crypt_ftr); if (rc) return rc; - char* adjusted_passwd = adjust_passwd(passwd); - char* hex_passwd = hexadj_passwd(passwd); +#ifdef CONFIG_HW_DISK_ENCRYPTION + printf("CONFIG_HW_DISK_ENCRYPTION present\n"); + if (is_hw_fde_enabled() && is_hw_disk_encryption((char*) crypt_ftr.crypto_type_name)) + has_hw_crypto = 1; +#endif - if (adjusted_passwd) { + //if (passwd) printf("passwd: '%s'\n", passwd); + char* adjusted_passwd; + if (!has_hw_crypto) + adjusted_passwd = adjust_passwd(passwd); + //if (adjusted_passwd) printf("adjusted_passwd: '%s'\n", adjusted_passwd); + char* hex_passwd = hexadj_passwd(passwd, has_hw_crypto); + //if (hex_passwd) printf("hex_passwd: '%s'\n", hex_passwd); + printf("has_hw_crypto is %i\n", has_hw_crypto); + if (!has_hw_crypto && adjusted_passwd) { int failed_decrypt_count = crypt_ftr.failed_decrypt_count; - rc = test_mount_encrypted_fs(&crypt_ftr, adjusted_passwd, + //printf("trying adjusted password '%s'\n", adjusted_passwd); + rc = test_mount_encrypted_fs(&crypt_ftr, hex_passwd, DATA_MNT_POINT, "userdata"); // Maybe the original one still works? if (rc) { // Don't double count this failure + //printf("trying passwd '%s'\n", passwd); crypt_ftr.failed_decrypt_count = failed_decrypt_count; rc = test_mount_encrypted_fs(&crypt_ftr, passwd, DATA_MNT_POINT, "userdata"); @@ -1305,16 +1399,23 @@ int cryptfs_check_passwd(char *passwd) printf("TWRP NOT Updating pattern to new format"); //cryptfs_changepw(CRYPT_TYPE_PATTERN, passwd); } else if (hex_passwd) { + //printf("trying hex_passwd '%s'\n", hex_passwd); rc = test_mount_encrypted_fs(&crypt_ftr, hex_passwd, DATA_MNT_POINT, "userdata"); } } free(adjusted_passwd); } else { - rc = test_mount_encrypted_fs(&crypt_ftr, passwd, - DATA_MNT_POINT, "userdata"); - if (rc && hex_passwd) { + if (hex_passwd) { + //printf("2trying hex_passwd '%s'\n", hex_passwd); rc = test_mount_encrypted_fs(&crypt_ftr, hex_passwd, + DATA_MNT_POINT, "userdata"); + } else { + rc = 1; + } + if (rc && passwd) { + //printf("2trying passwd '%s'\n", passwd); + rc = test_mount_encrypted_fs(&crypt_ftr, passwd, DATA_MNT_POINT, "userdata"); } } @@ -1323,7 +1424,7 @@ int cryptfs_check_passwd(char *passwd) free(hex_passwd); /*if (rc == 0 && crypt_ftr.crypt_type != CRYPT_TYPE_DEFAULT) { - printf("cryptfs_check_passwd update expiry time?\n"); + printf("cryptfs_check_passwd update expiry time?\n"); cryptfs_clear_password(); password = strdup(passwd); struct timespec now; diff --git a/crypto/lollipop/main.c b/crypto/lollipop/main.c new file mode 100644 index 000000000..4edec861b --- /dev/null +++ b/crypto/lollipop/main.c @@ -0,0 +1,35 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "cryptfs.h" +#include "cutils/properties.h" +#include "crypto_scrypt.h" +#include + +int main() { + printf("blah\n"); + set_partition_data("/dev/block/mmcblk0p28", "/dev/block/mmcblk0p27", "ext4"); + printf("blah2\n"); + int ret = cryptfs_check_passwd("30303030"); + //int ret = cryptfs_check_passwd("0000"); + return 0; +} diff --git a/partition.cpp b/partition.cpp index ef29bb6b3..87ba0bc66 100644 --- a/partition.cpp +++ b/partition.cpp @@ -259,6 +259,7 @@ bool TWPartition::Process_Fstab_Line(string Line, bool Display_Error) { Wipe_Available_in_GUI = true; Can_Be_Backed_Up = true; } else if (Mount_Point == "/data") { + UnMount(false); // added in case /data is mounted as tmpfs for qcom hardware decrypt Display_Name = "Data"; Backup_Display_Name = Display_Name; Storage_Name = Display_Name; diff --git a/prebuilt/Android.mk b/prebuilt/Android.mk index 07e24e39e..1449dc8af 100644 --- a/prebuilt/Android.mk +++ b/prebuilt/Android.mk @@ -131,6 +131,9 @@ ifeq ($(TW_INCLUDE_CRYPTO), true) RELINK_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libcryptfslollipop.so RELINK_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libcrypto.so RELINK_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libhardware.so + ifeq ($(TARGET_HW_DISK_ENCRYPTION),true) + RELINK_SOURCE_FILES += $(TARGET_OUT)/vendor/lib/libcryptfs_hw.so + endif endif ifeq ($(TARGET_USERIMAGES_USE_EXT4), true) RELINK_SOURCE_FILES += $(TARGET_OUT_EXECUTABLES)/make_ext4fs -- cgit v1.2.3