From 6b99d61baaee529c181a663a5f205b66c91141ff Mon Sep 17 00:00:00 2001 From: Neeraj Soni Date: Tue, 9 Jul 2019 11:16:15 +0530 Subject: cryptfs_hw: implement new hal support for vold BUG: b/121350843 vold communication with qseecom tee device should go through hal interface instead of directly using kernel ioctls. Change-Id: I43ea11b1b008e26ca3598697f50375136dd267f5 Signed-off-by: Neeraj Soni --- Android.bp | 12 +- cryptfs_hw.c | 403 --------------------------------------------------------- cryptfs_hw.cpp | 134 +++++++++++++++++++ cryptfs_hw.h | 2 +- 4 files changed, 144 insertions(+), 407 deletions(-) delete mode 100644 cryptfs_hw.c create mode 100644 cryptfs_hw.cpp diff --git a/Android.bp b/Android.bp index 5698fb3..edcc386 100644 --- a/Android.bp +++ b/Android.bp @@ -1,4 +1,4 @@ -sourceFiles = ["cryptfs_hw.c"] +sourceFiles = ["cryptfs_hw.cpp"] commonSharedLibraries = [ "libcutils", @@ -6,17 +6,23 @@ commonSharedLibraries = [ "libdl", "libhardware", "liblog", + "libhwbinder", + "libhidlbase", + "libhidltransport", + "libbinder", + "vendor.qti.hardware.cryptfshw@1.0", ] cc_library_shared { name: "libcryptfs_hw", header_libs: ["qseecom-kernel-headers", - "libhardware_headers"], - cflags: ["-DCONFIG_HW_DISK_ENCRYPTION"], + "libhardware_headers", + "libcryptfshw_hidl_headers",], srcs: sourceFiles, shared_libs: commonSharedLibraries, owner: "qti", + product_specific: true, } cc_library_headers { diff --git a/cryptfs_hw.c b/cryptfs_hw.c deleted file mode 100644 index d16c47b..0000000 --- a/cryptfs_hw.c +++ /dev/null @@ -1,403 +0,0 @@ -/* Copyright (c) 2014, 2017, The Linux Foundation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * * Neither the name of The Linux Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "cutils/log.h" -#include "cutils/properties.h" -#include "cutils/android_reboot.h" -#include "cryptfs_hw.h" - -/* - * 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 - * password further, HW would wipe all disk encryption related crypto data - * and would return an error ERR_MAX_PASSWORD_ATTEMPTS to VOLD. VOLD would - * wipe userdata partition once this error is received. - */ -#define ERR_MAX_PASSWORD_ATTEMPTS -10 -#define MAX_PASSWORD_LEN 32 -#define QTI_ICE_STORAGE_UFS 1 -#define QTI_ICE_STORAGE_SDCC 2 -#define SET_HW_DISK_ENC_KEY 1 -#define UPDATE_HW_DISK_ENC_KEY 2 - -#define CRYPTFS_HW_KMS_CLEAR_KEY 0 -#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 -#define CRYPTFS_HW_CREATE_KEY_FAILED -7 - -#define CRYPTFS_HW_ALGO_MODE_AES_XTS 0x3 - -enum cryptfs_hw_key_management_usage_type { - CRYPTFS_HW_KM_USAGE_DISK_ENCRYPTION = 0x01, - CRYPTFS_HW_KM_USAGE_FILE_ENCRYPTION = 0x02, - CRYPTFS_HW_KM_USAGE_UFS_ICE_DISK_ENCRYPTION = 0x03, - CRYPTFS_HW_KM_USAGE_SDCC_ICE_DISK_ENCRYPTION = 0x04, - CRYPTFS_HW_KM_USAGE_MAX -}; - -static inline void* secure_memset(void* v, int c , size_t n) -{ - volatile unsigned char* p = (volatile unsigned char* )v; - while (n--) *p++ = c; - return v; -} - -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; - memcpy(dst, src, min_size); - return min_size; -} - -static int cryptfs_hw_create_key(enum cryptfs_hw_key_management_usage_type usage, - unsigned char *hash32) -{ - struct qseecom_create_key_req req; - int qseecom_fd; - int32_t ret; - - if (usage < CRYPTFS_HW_KM_USAGE_DISK_ENCRYPTION || - usage >= CRYPTFS_HW_KM_USAGE_MAX) { - SLOGE("Error:: unsupported usage %d\n", usage); - return CRYPTFS_HW_CREATE_KEY_FAILED; - } - - qseecom_fd = open("/dev/qseecom", O_RDWR); - if (qseecom_fd < 0) { - SLOGE("Error::Failed to open /dev/qseecom device\n"); - return CRYPTFS_HW_CREATE_KEY_FAILED;; - } - - if (!hash32) { - secure_memset((void *)req.hash32, 0, QSEECOM_HASH_SIZE); - } else { - memscpy((void *)req.hash32, QSEECOM_HASH_SIZE, (void *)hash32, - QSEECOM_HASH_SIZE); - } - - req.usage = (enum qseecom_key_management_usage_type)usage; - ret = ioctl(qseecom_fd, QSEECOM_IOCTL_CREATE_KEY_REQ, &req); - if (ret) { - SLOGE("Error::ioctl call to create encryption key for usage %d failed with ret = %d, errno = %d\n", - usage, ret, errno); - if (errno == ERANGE) - ret = CRYPTFS_HW_KMS_MAX_FAILURE; - else - ret = CRYPTFS_HW_CREATE_KEY_FAILED; - } else { - SLOGE("SUCESS::ioctl call to create encryption key for usage %d success with ret = %d\n", - usage, ret); - } - close(qseecom_fd); - return ret; -} - -static int __cryptfs_hw_wipe_clear_key(enum cryptfs_hw_key_management_usage_type usage, int wipe_key_flag) -{ - struct qseecom_wipe_key_req req; - int32_t ret; - int qseecom_fd; - - if (usage < CRYPTFS_HW_KM_USAGE_DISK_ENCRYPTION || - usage >= CRYPTFS_HW_KM_USAGE_MAX) { - SLOGE("Error:: unsupported usage %d\n", usage); - return -1; - } - qseecom_fd = open("/dev/qseecom", O_RDWR); - if (qseecom_fd < 0) { - SLOGE("Error::Failed to open /dev/qseecom device\n"); - return -1; - } - - req.usage = (enum qseecom_key_management_usage_type)usage; - req.wipe_key_flag = wipe_key_flag; - ret = ioctl(qseecom_fd, QSEECOM_IOCTL_WIPE_KEY_REQ, &req); - close(qseecom_fd); - return ret; -} - -static int cryptfs_hw_wipe_key(enum cryptfs_hw_key_management_usage_type usage) -{ - int32_t ret; - - ret = __cryptfs_hw_wipe_clear_key(usage, CRYPTFS_HW_KMS_WIPE_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_WIPE_KEY_FAILED; - } else { - SLOGE("SUCCESS::ioctl call to wipe the encryption key for usage %d success with ret = %d\n", - usage, ret); - } - return ret; -} - -#ifdef QSEECOM_IOCTL_SET_ICE_INFO -int set_ice_param(int flag) -{ - int qseecom_fd, ret = -1; - struct qseecom_ice_data_t ice_data = {0}; - qseecom_fd = open("/dev/qseecom", O_RDWR); - if (qseecom_fd < 0) - return ret; - ice_data.flag = flag; - ret = ioctl(qseecom_fd, QSEECOM_IOCTL_SET_ICE_INFO, &ice_data); - close(qseecom_fd); - return ret; -} -#else -int set_ice_param(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) -{ - struct qseecom_update_key_userinfo_req req; - int qseecom_fd; - int32_t ret; - - if (usage < CRYPTFS_HW_KM_USAGE_DISK_ENCRYPTION || - usage >= CRYPTFS_HW_KM_USAGE_MAX) { - SLOGE("Error:: unsupported usage %d\n", usage); - return CRYPTFS_HW_UPDATE_KEY_FAILED; - } - qseecom_fd = open("/dev/qseecom", O_RDWR); - if (qseecom_fd < 0) { - SLOGE("Error::Failed to open /dev/qseecom device\n"); - return CRYPTFS_HW_UPDATE_KEY_FAILED; - } - - req.usage = (enum qseecom_key_management_usage_type)usage; - if (!current_hash32) { - secure_memset((void *)req.current_hash32, 0, QSEECOM_HASH_SIZE); - } else { - memscpy((void *)req.current_hash32, QSEECOM_HASH_SIZE, (void *)current_hash32, - QSEECOM_HASH_SIZE); - } - if (!new_hash32) { - secure_memset((void *)req.new_hash32, 0, QSEECOM_HASH_SIZE); - } else { - memscpy((void *)req.new_hash32, QSEECOM_HASH_SIZE, (void *)new_hash32, - QSEECOM_HASH_SIZE); - } - - ret = ioctl(qseecom_fd, QSEECOM_IOCTL_UPDATE_KEY_USER_INFO_REQ, &req); - if (ret) { - SLOGE("Error::ioctl call to update the encryption key for usage %d failed with ret = %d, errno = %d\n", - usage, ret, errno); - if (errno == ERANGE) - ret = CRYPTFS_HW_KMS_MAX_FAILURE; - else - ret = CRYPTFS_HW_UPDATE_KEY_FAILED; - } else { - SLOGE("SUCCESS::ioctl call to update the encryption key for usage %d success with ret = %d\n", - usage, ret); - } - close(qseecom_fd); - return ret; -} - -static int map_usage(int usage) -{ - int storage_type = is_ice_enabled(); - if (usage == CRYPTFS_HW_KM_USAGE_DISK_ENCRYPTION) { - if (storage_type == QTI_ICE_STORAGE_UFS) { - return CRYPTFS_HW_KM_USAGE_UFS_ICE_DISK_ENCRYPTION; - } - else if (storage_type == QTI_ICE_STORAGE_SDCC) { - return CRYPTFS_HW_KM_USAGE_SDCC_ICE_DISK_ENCRYPTION; - } - } - return usage; -} - -static unsigned char* get_tmp_passwd(const char* passwd) -{ - int passwd_len = 0; - unsigned char * tmp_passwd = NULL; - if(passwd) { - tmp_passwd = (unsigned char*)malloc(MAX_PASSWORD_LEN); - if(tmp_passwd) { - secure_memset(tmp_passwd, 0, MAX_PASSWORD_LEN); - passwd_len = strnlen(passwd, MAX_PASSWORD_LEN); - memcpy(tmp_passwd, passwd, passwd_len); - } else { - SLOGE("%s: Failed to allocate memory for tmp passwd \n", __func__); - } - } else { - SLOGE("%s: Passed argument is NULL \n", __func__); - } - return tmp_passwd; -} - -static int is_qseecom_up() -{ - int i = 0; - char value[PROPERTY_VALUE_MAX] = {0}; - - for (; imodule_api_version; -} - -int should_use_keymaster() -{ - /* - * HW FDE key should be tied to keymaster - */ - return 1; -} diff --git a/cryptfs_hw.cpp b/cryptfs_hw.cpp new file mode 100644 index 0000000..2d9af7a --- /dev/null +++ b/cryptfs_hw.cpp @@ -0,0 +1,134 @@ +/* Copyright (c) 2014, 2017, 2019 The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "cutils/log.h" +#include "cutils/properties.h" +#include "cryptfs_hw.h" +#include "CryptfsHw.h" + +using android::sp; +using vendor::qti::hardware::cryptfshw::V1_0::ICryptfsHw; +using ::android::hardware::Return; +using ::android::hardware::Void; + +#define QTI_ICE_STORAGE_UFS 1 +#define QTI_ICE_STORAGE_SDCC 2 + +#ifdef QSEECOM_IOCTL_SET_ICE_INFO +int set_ice_param(int flag) +{ + int rc = -1; + sp cryptfshwService = ICryptfsHw::getService(); + if (cryptfshwService.get() == nullptr) { + ALOGE("Failed to get Cryptfshw service"); + return rc; + } + rc = cryptfshwService->setIceParam(flag); + return rc; +} +#else +int set_ice_param(int flag) +{ + return -1; +} +#endif + +int set_hw_device_encryption_key(const char* passwd, const char* enc_mode) +{ + int rc = -1; + sp cryptfshwService = ICryptfsHw::getService(); + if (cryptfshwService.get() == nullptr) { + ALOGE("Failed to get Cryptfshw service"); + return rc; + } + rc = cryptfshwService->setKey(passwd, enc_mode); + return rc; +} + +int update_hw_device_encryption_key(const char* oldpw, const char* newpw, const char* enc_mode) +{ + int rc = -1; + sp cryptfshwService = ICryptfsHw::getService(); + if (cryptfshwService.get() == nullptr) { + ALOGE("Failed to get Cryptfshw service"); + return rc; + } + rc = cryptfshwService->updateKey(oldpw, newpw, enc_mode); + return rc; +} + +unsigned int is_hw_disk_encryption(const char* encryption_mode) +{ + int ret = 0; + if(encryption_mode) { + if (!strcmp(encryption_mode, "aes-xts")) { + SLOGD("HW based disk encryption is enabled \n"); + ret = 1; + } + } + return ret; +} + +int is_ice_enabled(void) +{ + char prop_storage[PATH_MAX]; + int storage_type = 0; + + if (property_get("ro.boot.bootdevice", prop_storage, "")) { + if (strstr(prop_storage, "ufs")) { + /* All UFS based devices has ICE in it. So we dont need + * to check if corresponding device exists or not + */ + storage_type = QTI_ICE_STORAGE_UFS; + } else if (strstr(prop_storage, "sdhc")) { + if (access("/dev/icesdcc", F_OK) != -1) + storage_type = QTI_ICE_STORAGE_SDCC; + } + } + return storage_type; +} + +int clear_hw_device_encryption_key() +{ + int rc = -1; + sp cryptfshwService = ICryptfsHw::getService(); + if (cryptfshwService.get() == nullptr) { + ALOGE("Failed to get Cryptfshw service"); + return rc; + } + rc = cryptfshwService->clearKey(); + return rc; +} + diff --git a/cryptfs_hw.h b/cryptfs_hw.h index 65321eb..d7ed51e 100644 --- a/cryptfs_hw.h +++ b/cryptfs_hw.h @@ -43,7 +43,7 @@ int update_hw_device_encryption_key(const char*, const char*, const char*); int clear_hw_device_encryption_key(); unsigned int is_hw_disk_encryption(const char*); int is_ice_enabled(void); -int should_use_keymaster(); +inline int should_use_keymaster(){return 1;} int set_ice_param(int flag); #ifdef __cplusplus -- cgit v1.2.3