summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Android.bp13
-rw-r--r--cryptfs_hw.c152
2 files changed, 129 insertions, 36 deletions
diff --git a/Android.bp b/Android.bp
index 5698fb3..ea6cbb0 100644
--- a/Android.bp
+++ b/Android.bp
@@ -10,12 +10,23 @@ commonSharedLibraries = [
cc_library_shared {
name: "libcryptfs_hw",
- header_libs: ["qseecom-kernel-headers",
+ header_libs: ["generated_kernel_headers",
"libhardware_headers"],
cflags: ["-DCONFIG_HW_DISK_ENCRYPTION"],
srcs: sourceFiles,
shared_libs: commonSharedLibraries,
+ product_variables: {
+ lineage: {
+ should_skip_waiting_for_qsee: {
+ cflags: ["-DSKIP_WAITING_FOR_QSEE"],
+ },
+ supports_legacy_hw_fde: {
+ cflags: ["-DLEGACY_HW_DISK_ENCRYPTION"],
+ },
+ },
+ },
+
owner: "qti",
}
diff --git a/cryptfs_hw.c b/cryptfs_hw.c
index 72d0133..482e28b 100644
--- a/cryptfs_hw.c
+++ b/cryptfs_hw.c
@@ -26,6 +26,8 @@
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#define LOG_TAG "Cryptfs_hw"
+
#include <stdlib.h>
#include <string.h>
#include <sys/limits.h>
@@ -43,6 +45,10 @@
#include "cutils/android_reboot.h"
#include "cryptfs_hw.h"
+#ifdef LEGACY_HW_DISK_ENCRYPTION
+#define QSEECOM_LIBRARY_NAME "libQSEEComAPI.so"
+#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
@@ -57,10 +63,15 @@
#define SET_HW_DISK_ENC_KEY 1
#define UPDATE_HW_DISK_ENC_KEY 2
-#define CRYPTFS_HW_KMS_CLEAR_KEY 0
+#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_WIPE_KEY 1
#define CRYPTFS_HW_UP_CHECK_COUNT 10
-#define CRYPTFS_HW_CLEAR_KEY_FAILED -11
#define CRYPTFS_HW_KMS_MAX_FAILURE -10
#define CRYPTFS_HW_UPDATE_KEY_FAILED -9
#define CRYPTFS_HW_WIPE_KEY_FAILED -8
@@ -85,6 +96,96 @@ static inline void* secure_memset(void* v, int c , size_t n)
return v;
}
+#ifdef LEGACY_HW_DISK_ENCRYPTION
+#ifdef SKIP_WAITING_FOR_QSEE
+static int is_qseecom_up()
+{
+ return 1;
+}
+#else
+static int is_qseecom_up()
+{
+ int i = 0;
+ char value[PROPERTY_VALUE_MAX] = {0};
+
+ for (; i<CRYPTFS_HW_UP_CHECK_COUNT; i++) {
+ property_get("sys.keymaster.loaded", value, "");
+ if (!strncmp(value, "true", PROPERTY_VALUE_MAX))
+ return 1;
+ usleep(100000);
+ }
+ return 0;
+}
+#endif
+
+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_NAME, 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;
+}
+
+static int cryptfs_hw_create_key(enum cryptfs_hw_key_management_usage_type usage,
+ unsigned char *hash32)
+{
+ if (load_qseecom_library())
+ return qseecom_create_key(usage, hash32);
+
+ return CRYPTFS_HW_CREATE_KEY_FAILED;
+}
+
+static int cryptfs_hw_wipe_key(enum cryptfs_hw_key_management_usage_type usage)
+{
+ if (load_qseecom_library())
+ return qseecom_wipe_key(usage);
+
+ return CRYPTFS_HW_WIPE_KEY_FAILED;
+}
+
+static int cryptfs_hw_update_key(enum cryptfs_hw_key_management_usage_type usage,
+ unsigned char *current_hash32, unsigned char *new_hash32)
+{
+ if (load_qseecom_library())
+ return qseecom_update_key(usage, current_hash32, new_hash32);
+
+ return CRYPTFS_HW_UPDATE_KEY_FAILED;
+}
+#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;
@@ -189,28 +290,12 @@ int set_ice_param(int flag)
return ret;
}
#else
-int set_ice_param(int flag)
+int set_ice_param(__unused int flag)
{
return -1;
}
#endif
-static int cryptfs_hw_clear_key(enum cryptfs_hw_key_management_usage_type usage)
-{
- int32_t ret;
-
- ret = __cryptfs_hw_wipe_clear_key(usage, CRYPTFS_HW_KMS_CLEAR_KEY);
- if (ret) {
- SLOGE("Error::ioctl call to wipe the encryption key for usage %d failed with ret = %d, errno = %d\n",
- usage, ret, errno);
- ret = CRYPTFS_HW_CLEAR_KEY_FAILED;
- } else {
- SLOGE("SUCCESS::ioctl call to wipe the encryption key for usage %d success with ret = %d\n",
- usage, ret);
- }
- return ret;
-}
-
static int cryptfs_hw_update_key(enum cryptfs_hw_key_management_usage_type usage,
unsigned char *current_hash32, unsigned char *new_hash32)
{
@@ -258,6 +343,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)
{
@@ -292,20 +378,6 @@ static unsigned char* get_tmp_passwd(const char* passwd)
return tmp_passwd;
}
-static int is_qseecom_up()
-{
- int i = 0;
- char value[PROPERTY_VALUE_MAX] = {0};
-
- for (; i<CRYPTFS_HW_UP_CHECK_COUNT; i++) {
- property_get("vendor.sys.keymaster.loaded", value, "");
- if (!strncmp(value, "true", PROPERTY_VALUE_MAX))
- return 1;
- usleep(100000);
- }
- return 0;
-}
-
/*
* For NON-ICE targets, it would return 0 on success. On ICE based targets,
* it would return key index in the ICE Key LUT
@@ -363,7 +435,6 @@ int is_ice_enabled(void)
{
char prop_storage[PATH_MAX];
int storage_type = 0;
- int fd;
/*
* Since HW FDE is a compile time flag (due to QSSI requirements),
@@ -411,15 +482,26 @@ static int get_keymaster_version()
int should_use_keymaster()
{
+ int rc = 1;
+#ifdef LEGACY_HW_DISK_ENCRYPTION
+ /*
+ * HW FDE key should be tied to keymaster only if
+ * new Keymaster is available
+ */
+ if (get_keymaster_version() != KEYMASTER_MODULE_API_VERSION_1_0) {
+ SLOGI("Keymaster version is not 1.0");
+ rc = 0;
+ }
+#else
/*
* HW FDE key should be tied to keymaster
* if version is above 0.3. this is to
* support msm8909 go target.
*/
- int rc = 1;
if (get_keymaster_version() == KEYMASTER_MODULE_API_VERSION_0_3) {
SLOGI("Keymaster version is 0.3");
rc = 0;
}
+#endif
return rc;
}