From 0e83c6004312fab088a1b9364a8f342721d0fc15 Mon Sep 17 00:00:00 2001 From: Neeraj Soni Date: Wed, 26 Jun 2019 19:18:14 +0530 Subject: cryptfs_hw: remove block disk encryption dependency on metadata partition Blocking inline crypto engine based disk encryption if metadata partition is enabled is not required as vold can check if crypto block device was created at first place or not. Also vold should pass the disk encryption key index to crypto driver to leverage all possible key slot usage in crypto engine. Change-Id: I00bea82f734ea50f2b51b0875ee23371de1b9896 Signed-off-by: Neeraj Soni --- cryptfs_hw.c | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/cryptfs_hw.c b/cryptfs_hw.c index ebf9381..d16c47b 100644 --- a/cryptfs_hw.c +++ b/cryptfs_hw.c @@ -68,8 +68,6 @@ #define CRYPTFS_HW_ALGO_MODE_AES_XTS 0x3 -#define METADATA_PARTITION_NAME "/dev/block/bootdevice/by-name/metadata" - enum cryptfs_hw_key_management_usage_type { CRYPTFS_HW_KM_USAGE_DISK_ENCRYPTION = 0x01, CRYPTFS_HW_KM_USAGE_FILE_ENCRYPTION = 0x02, @@ -179,7 +177,7 @@ static int cryptfs_hw_wipe_key(enum cryptfs_hw_key_management_usage_type usage) int set_ice_param(int flag) { int qseecom_fd, ret = -1; - struct qseecom_ice_data_t ice_data; + struct qseecom_ice_data_t ice_data = {0}; qseecom_fd = open("/dev/qseecom", O_RDWR); if (qseecom_fd < 0) return ret; @@ -363,19 +361,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), - * this API conflicts with Metadata encryption even when ICE is - * enabled, as it encrypts the whole disk instead. Adding this - * workaround to return 0 if metadata partition is present. - */ - - if (access(METADATA_PARTITION_NAME, F_OK) == 0) { - SLOGI("Metadata partition, returning false"); - return 0; - } if (property_get("ro.boot.bootdevice", prop_storage, "")) { if (strstr(prop_storage, "ufs")) { -- cgit v1.2.3 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