diff options
author | Michael Bestas <mkbestas@lineageos.org> | 2017-12-20 19:12:59 +0200 |
---|---|---|
committer | Michael Bestas <mkbestas@lineageos.org> | 2017-12-27 13:12:16 +0000 |
commit | f51f69d5c7f7880c1adb4d620fb40161b2984170 (patch) | |
tree | f7f2ddefd84147f66d607029229291932647b506 | |
parent | 2ab4e3f1067e4e18ace7c3106d826e751e0a2c9d (diff) | |
download | android_vendor_qcom_opensource_cryptfs_hw-f51f69d5c7f7880c1adb4d620fb40161b2984170.tar.gz android_vendor_qcom_opensource_cryptfs_hw-f51f69d5c7f7880c1adb4d620fb40161b2984170.tar.bz2 android_vendor_qcom_opensource_cryptfs_hw-f51f69d5c7f7880c1adb4d620fb40161b2984170.zip |
cryptfs_hw: Add compatibility for pre-O hw crypto
* Restore compatibility for pre-O way of hw crypto
interaction with qsee as the new way is not
compatible with old blobs.
* Old blobs and current OSS keymaster still use the
old property to check if qseecomd is loaded.
* This conditionally reverts:
cryptfs_hw: Add new APIs for key management
84ac4882d6feeceb24e983a4eaba1d148c2ba3e6
cryptfs_hw: Use HW keymaster for FDE keys
a5d3a02eb13362490222ac2a7eefde6543546e31
cryptfs_hw: Wait for qseecom daemon to start FDE operation
b01c6ec9373bee3e9d71d2300ebce7c287c3d687
Change-Id: I9a5db406c16c3610237a1b85fbfab5c0d63e4960
-rw-r--r-- | Android.mk | 4 | ||||
-rwxr-xr-x | cryptfs_hw.c | 107 |
2 files changed, 109 insertions, 2 deletions
@@ -37,5 +37,9 @@ ifeq ($(TARGET_USE_UFS_ICE),true) LOCAL_CFLAGS += -DUSE_ICE_FOR_STORAGE_ENCRYPTION endif +ifeq ($(TARGET_LEGACY_HW_DISK_ENCRYPTION),true) +LOCAL_CFLAGS += -DLEGACY_HW_DISK_ENCRYPTION +endif + include $(BUILD_SHARED_LIBRARY) endif diff --git a/cryptfs_hw.c b/cryptfs_hw.c index c9d11dd..827d846 100755 --- a/cryptfs_hw.c +++ b/cryptfs_hw.c @@ -42,6 +42,14 @@ #include "hardware.h" #include "cryptfs_hw.h" +#ifdef LEGACY_HW_DISK_ENCRYPTION +#if defined(__LP64__) +#define QSEECOM_LIBRARY_PATH "/vendor/lib64/libQSEEComAPI.so" +#else +#define QSEECOM_LIBRARY_PATH "/vendor/lib/libQSEEComAPI.so" +#endif +#endif + /* * When device comes up or when user tries to change the password, user can * try wrong password upto a certain number of times. If user enters wrong @@ -61,6 +69,13 @@ static unsigned int cpu_id[] = { 239, /* MSM8939 SOC ID */ }; +#ifdef LEGACY_HW_DISK_ENCRYPTION +static int loaded_library = 0; +static int (*qseecom_create_key)(int, void*); +static int (*qseecom_update_key)(int, void*, void*); +static int (*qseecom_wipe_key)(int); +#endif + #define CRYPTFS_HW_KMS_CLEAR_KEY 0 #define CRYPTFS_HW_KMS_WIPE_KEY 1 #define CRYPTFS_HW_UP_CHECK_COUNT 10 @@ -85,6 +100,24 @@ static inline void* secure_memset(void* v, int c , size_t n) return v; } +#ifdef LEGACY_HW_DISK_ENCRYPTION +static int cryptfs_hw_create_key(enum cryptfs_hw_key_management_usage_type usage, + unsigned char *hash32) +{ + return qseecom_create_key(usage, hash32); +} + +static int cryptfs_hw_wipe_key(enum cryptfs_hw_key_management_usage_type usage) +{ + return qseecom_wipe_key(usage); +} + +static int cryptfs_hw_update_key(enum cryptfs_hw_key_management_usage_type usage, + unsigned char *current_hash32, unsigned char *new_hash32) +{ + return qseecom_update_key(usage, current_hash32, new_hash32); +} +#else static size_t memscpy(void *dst, size_t dst_size, const void *src, size_t src_size) { size_t min_size = (dst_size < src_size) ? dst_size : src_size; @@ -237,6 +270,7 @@ static int cryptfs_hw_update_key(enum cryptfs_hw_key_management_usage_type usage close(qseecom_fd); return ret; } +#endif static int map_usage(int usage) { @@ -277,7 +311,11 @@ static int is_qseecom_up() char value[PROPERTY_VALUE_MAX] = {0}; for (; i<CRYPTFS_HW_UP_CHECK_COUNT; i++) { +#ifdef LEGACY_HW_DISK_ENCRYPTION + property_get("sys.keymaster.loaded", value, ""); +#else property_get("sys.listeners.registered", value, ""); +#endif if (!strncmp(value, "true", PROPERTY_VALUE_MAX)) return 1; usleep(100000); @@ -286,6 +324,50 @@ static int is_qseecom_up() return 0; } +#ifdef LEGACY_HW_DISK_ENCRYPTION +static int load_qseecom_library() +{ + const char *error = NULL; + if (loaded_library) + return loaded_library; + + if (!is_qseecom_up()) { + SLOGE("Timed out waiting for QSEECom listeners. Aborting FDE key operation"); + return 0; + } + + void * handle = dlopen(QSEECOM_LIBRARY_PATH, RTLD_NOW); + if (handle) { + dlerror(); /* Clear any existing error */ + *(void **) (&qseecom_create_key) = dlsym(handle, "QSEECom_create_key"); + + if ((error = dlerror()) == NULL) { + SLOGD("Success loading QSEECom_create_key \n"); + *(void **) (&qseecom_update_key) = dlsym(handle, "QSEECom_update_key_user_info"); + if ((error = dlerror()) == NULL) { + SLOGD("Success loading QSEECom_update_key_user_info\n"); + *(void **) (&qseecom_wipe_key) = dlsym(handle, "QSEECom_wipe_key"); + if ((error = dlerror()) == NULL) { + loaded_library = 1; + SLOGD("Success loading QSEECom_wipe_key \n"); + } + else + SLOGE("Error %s loading symbols for QSEECom APIs \n", error); + } + else + SLOGE("Error %s loading symbols for QSEECom APIs \n", error); + } + } else { + SLOGE("Could not load libQSEEComAPI.so \n"); + } + + if (error) + dlclose(handle); + + return loaded_library; +} +#endif + /* * For NON-ICE targets, it would return 0 on success. On ICE based targets, * it would return key index in the ICE Key LUT @@ -293,7 +375,11 @@ static int is_qseecom_up() static int set_key(const char* currentpasswd, const char* passwd, const char* enc_mode, int operation) { int err = -1; - if (is_hw_disk_encryption(enc_mode) && is_qseecom_up()) { + if (is_hw_disk_encryption(enc_mode) && is_qseecom_up() +#ifdef LEGACY_HW_DISK_ENCRYPTION + && load_qseecom_library() +#endif + ) { unsigned char* tmp_passwd = get_tmp_passwd(passwd); unsigned char* tmp_currentpasswd = get_tmp_passwd(currentpasswd); if (tmp_passwd) { @@ -413,7 +499,11 @@ int is_ice_enabled(void) int clear_hw_device_encryption_key() { - if(is_qseecom_up()) + if (is_qseecom_up() +#ifdef LEGACY_HW_DISK_ENCRYPTION + && load_qseecom_library() +#endif + ) return cryptfs_hw_wipe_key(map_usage(CRYPTFS_HW_KM_USAGE_DISK_ENCRYPTION)); return 0; } @@ -433,8 +523,21 @@ static int get_keymaster_version() int should_use_keymaster() { +#ifdef LEGACY_HW_DISK_ENCRYPTION + /* + * HW FDE key would be tied to keymaster only if + * new Keymaster is available + */ + int rc = 0; + if (get_keymaster_version() != KEYMASTER_MODULE_API_VERSION_1_0) { + SLOGI("Keymaster version is not 1.0"); + return rc; + } +#else /* * HW FDE key should be tied to keymaster */ +#endif + return 1; } |