Loading drivers/crypto/msm/ice.c +55 −24 Original line number Diff line number Diff line /* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -74,6 +74,9 @@ static inline void pfk_clear_on_reset(void) #define QCOM_ICE_MAX_BIST_CHECK_COUNT 100 #define QCOM_ICE_UFS 10 #define QCOM_ICE_SDCC 20 #define QCOM_ICE_ENCRYPT 0x1 #define QCOM_ICE_DECRYPT 0x2 #define QCOM_SECT_LEN_IN_BYTE 512 struct ice_clk_info { struct list_head list; Loading Loading @@ -123,6 +126,11 @@ struct ice_device { ktime_t ice_reset_complete_time; }; static int ice_fde_flag; static unsigned long userdata_start; static unsigned long userdata_end; static struct ice_crypto_setting ice_data; static int qti_ice_setting_config(struct request *req, struct platform_device *pdev, struct ice_crypto_setting *crypto_data, Loading @@ -149,19 +157,49 @@ static int qti_ice_setting_config(struct request *req, memcpy(&setting->crypto_data, crypto_data, sizeof(setting->crypto_data)); if (rq_data_dir(req) == WRITE) if (rq_data_dir(req) == WRITE && (ice_fde_flag & QCOM_ICE_ENCRYPT)) setting->encr_bypass = false; else if (rq_data_dir(req) == READ) else if (rq_data_dir(req) == READ && (ice_fde_flag & QCOM_ICE_DECRYPT)) setting->decr_bypass = false; else { /* Should I say BUG_ON */ setting->encr_bypass = true; setting->decr_bypass = true; pr_debug("%s direction unknown", __func__); } } return 0; } void qcom_ice_set_fde_flag(int flag) { ice_fde_flag = flag; pr_debug("%s read_write setting %d\n", __func__, ice_fde_flag); } EXPORT_SYMBOL(qcom_ice_set_fde_flag); int qcom_ice_set_fde_conf(sector_t s_sector, sector_t size, int index, int mode) { userdata_start = s_sector; userdata_end = s_sector + size; if (INT_MAX - s_sector < size) { WARN_ON(1); return -EINVAL; } ice_data.key_index = index; ice_data.algo_mode = mode; ice_data.key_size = ICE_CRYPTO_KEY_SIZE_256; ice_data.key_mode = ICE_CRYPTO_USE_LUT_SW_KEY; pr_debug("%s sector info set start %lu end %lu\n", __func__, userdata_start, userdata_end); return 0; } EXPORT_SYMBOL(qcom_ice_set_fde_conf); static int qcom_ice_enable_clocks(struct ice_device *, bool); Loading Loading @@ -1445,11 +1483,10 @@ static int qcom_ice_config_start(struct platform_device *pdev, struct request *req, struct ice_data_setting *setting, bool async) { struct ice_crypto_setting *crypto_data; struct ice_crypto_setting pfk_crypto_data = {0}; union map_info *info; int ret = 0; bool is_pfe = false; sector_t data_size; if (!pdev || !req || !setting) { pr_err("%s: Invalid params passed\n", __func__); Loading Loading @@ -1484,28 +1521,22 @@ static int qcom_ice_config_start(struct platform_device *pdev, &pfk_crypto_data, setting); } /* * info field in req->end_io_data could be used by mulitple dm or * non-dm entities. To ensure that we are running operation on dm * based request, check BIO_DONT_FREE flag */ if (bio_flagged(req->bio, BIO_INLINECRYPT)) { info = dm_get_rq_mapinfo(req); if (!info) { pr_debug("%s info not available in request\n", __func__); if (ice_fde_flag == 0) return 0; } crypto_data = (struct ice_crypto_setting *)info->ptr; if (!crypto_data) { pr_err("%s crypto_data not available in request\n", __func__); return -EINVAL; } if ((req->__sector >= userdata_start) && (req->__sector < userdata_end)) { /* * Ugly hack to address non-block-size aligned userdata end address in * eMMC based devices. */ data_size = req->__data_len/QCOM_SECT_LEN_IN_BYTE; if ((req->__sector + data_size) > userdata_end) return 0; else return qti_ice_setting_config(req, pdev, crypto_data, setting); &ice_data, setting); } /* Loading drivers/misc/qseecom.c +25 −0 Original line number Diff line number Diff line Loading @@ -6966,6 +6966,31 @@ static inline long qseecom_ioctl(struct file *file, pr_err("failed qseecom_register_listener: %d\n", ret); break; } case QSEECOM_IOCTL_SET_ICE_INFO: { struct qseecom_ice_data_t ice_data; ret = copy_from_user(&ice_data, argp, sizeof(ice_data)); if (ret) { pr_err("copy_from_user failed\n"); return -EFAULT; } qcom_ice_set_fde_flag(ice_data.flag); break; } case QSEECOM_IOCTL_SET_ENCDEC_INFO: { struct qseecom_encdec_conf_t conf; ret = copy_from_user(&conf, argp, sizeof(conf)); if (ret) { pr_err("copy_from_user failed\n"); return -EFAULT; } ret = qcom_ice_set_fde_conf(conf.start_sector, conf.fs_size, conf.index, conf.mode); break; } case QSEECOM_IOCTL_UNREGISTER_LISTENER_REQ: { if ((data->listener.id == 0) || (data->type != QSEECOM_LISTENER_SERVICE)) { Loading include/crypto/ice.h +3 −1 Original line number Diff line number Diff line /* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -53,6 +53,8 @@ typedef void (*ice_error_cb)(void *, u32 error); struct qcom_ice_variant_ops *qcom_ice_get_variant_ops(struct device_node *node); struct platform_device *qcom_ice_get_pdevice(struct device_node *node); void qcom_ice_set_fde_flag(int flag); int qcom_ice_set_fde_conf(sector_t strt, sector_t size, int idx, int mode); #ifdef CONFIG_CRYPTO_DEV_QCOM_ICE int qcom_ice_setup_ice_hw(const char *storage_type, int enable); Loading include/uapi/linux/qseecom.h +16 −0 Original line number Diff line number Diff line Loading @@ -277,6 +277,17 @@ struct qseecom_ce_info_req { struct qseecom_ce_pipe_entry ce_pipe_entry[MAX_CE_PIPE_PAIR_PER_UNIT]; }; struct qseecom_ice_data_t { int flag; }; struct qseecom_encdec_conf_t { __le64 start_sector; size_t fs_size; int index; int mode; }; #define SG_ENTRY_SZ sizeof(struct qseecom_sg_entry) #define SG_ENTRY_SZ_64BIT sizeof(struct qseecom_sg_entry_64bit) Loading Loading @@ -385,5 +396,10 @@ struct file; #define QSEECOM_IOCTL_QUERY_CE_PIPE_INFO \ _IOWR(QSEECOM_IOC_MAGIC, 42, struct qseecom_ce_info_req) #define QSEECOM_IOCTL_SET_ICE_INFO \ _IOWR(QSEECOM_IOC_MAGIC, 43, struct qseecom_ice_data_t) #define QSEECOM_IOCTL_SET_ENCDEC_INFO \ _IOWR(QSEECOM_IOC_MAGIC, 44, struct qseecom_encdec_conf_t) #endif /* _UAPI_QSEECOM_H_ */ Loading
drivers/crypto/msm/ice.c +55 −24 Original line number Diff line number Diff line /* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -74,6 +74,9 @@ static inline void pfk_clear_on_reset(void) #define QCOM_ICE_MAX_BIST_CHECK_COUNT 100 #define QCOM_ICE_UFS 10 #define QCOM_ICE_SDCC 20 #define QCOM_ICE_ENCRYPT 0x1 #define QCOM_ICE_DECRYPT 0x2 #define QCOM_SECT_LEN_IN_BYTE 512 struct ice_clk_info { struct list_head list; Loading Loading @@ -123,6 +126,11 @@ struct ice_device { ktime_t ice_reset_complete_time; }; static int ice_fde_flag; static unsigned long userdata_start; static unsigned long userdata_end; static struct ice_crypto_setting ice_data; static int qti_ice_setting_config(struct request *req, struct platform_device *pdev, struct ice_crypto_setting *crypto_data, Loading @@ -149,19 +157,49 @@ static int qti_ice_setting_config(struct request *req, memcpy(&setting->crypto_data, crypto_data, sizeof(setting->crypto_data)); if (rq_data_dir(req) == WRITE) if (rq_data_dir(req) == WRITE && (ice_fde_flag & QCOM_ICE_ENCRYPT)) setting->encr_bypass = false; else if (rq_data_dir(req) == READ) else if (rq_data_dir(req) == READ && (ice_fde_flag & QCOM_ICE_DECRYPT)) setting->decr_bypass = false; else { /* Should I say BUG_ON */ setting->encr_bypass = true; setting->decr_bypass = true; pr_debug("%s direction unknown", __func__); } } return 0; } void qcom_ice_set_fde_flag(int flag) { ice_fde_flag = flag; pr_debug("%s read_write setting %d\n", __func__, ice_fde_flag); } EXPORT_SYMBOL(qcom_ice_set_fde_flag); int qcom_ice_set_fde_conf(sector_t s_sector, sector_t size, int index, int mode) { userdata_start = s_sector; userdata_end = s_sector + size; if (INT_MAX - s_sector < size) { WARN_ON(1); return -EINVAL; } ice_data.key_index = index; ice_data.algo_mode = mode; ice_data.key_size = ICE_CRYPTO_KEY_SIZE_256; ice_data.key_mode = ICE_CRYPTO_USE_LUT_SW_KEY; pr_debug("%s sector info set start %lu end %lu\n", __func__, userdata_start, userdata_end); return 0; } EXPORT_SYMBOL(qcom_ice_set_fde_conf); static int qcom_ice_enable_clocks(struct ice_device *, bool); Loading Loading @@ -1445,11 +1483,10 @@ static int qcom_ice_config_start(struct platform_device *pdev, struct request *req, struct ice_data_setting *setting, bool async) { struct ice_crypto_setting *crypto_data; struct ice_crypto_setting pfk_crypto_data = {0}; union map_info *info; int ret = 0; bool is_pfe = false; sector_t data_size; if (!pdev || !req || !setting) { pr_err("%s: Invalid params passed\n", __func__); Loading Loading @@ -1484,28 +1521,22 @@ static int qcom_ice_config_start(struct platform_device *pdev, &pfk_crypto_data, setting); } /* * info field in req->end_io_data could be used by mulitple dm or * non-dm entities. To ensure that we are running operation on dm * based request, check BIO_DONT_FREE flag */ if (bio_flagged(req->bio, BIO_INLINECRYPT)) { info = dm_get_rq_mapinfo(req); if (!info) { pr_debug("%s info not available in request\n", __func__); if (ice_fde_flag == 0) return 0; } crypto_data = (struct ice_crypto_setting *)info->ptr; if (!crypto_data) { pr_err("%s crypto_data not available in request\n", __func__); return -EINVAL; } if ((req->__sector >= userdata_start) && (req->__sector < userdata_end)) { /* * Ugly hack to address non-block-size aligned userdata end address in * eMMC based devices. */ data_size = req->__data_len/QCOM_SECT_LEN_IN_BYTE; if ((req->__sector + data_size) > userdata_end) return 0; else return qti_ice_setting_config(req, pdev, crypto_data, setting); &ice_data, setting); } /* Loading
drivers/misc/qseecom.c +25 −0 Original line number Diff line number Diff line Loading @@ -6966,6 +6966,31 @@ static inline long qseecom_ioctl(struct file *file, pr_err("failed qseecom_register_listener: %d\n", ret); break; } case QSEECOM_IOCTL_SET_ICE_INFO: { struct qseecom_ice_data_t ice_data; ret = copy_from_user(&ice_data, argp, sizeof(ice_data)); if (ret) { pr_err("copy_from_user failed\n"); return -EFAULT; } qcom_ice_set_fde_flag(ice_data.flag); break; } case QSEECOM_IOCTL_SET_ENCDEC_INFO: { struct qseecom_encdec_conf_t conf; ret = copy_from_user(&conf, argp, sizeof(conf)); if (ret) { pr_err("copy_from_user failed\n"); return -EFAULT; } ret = qcom_ice_set_fde_conf(conf.start_sector, conf.fs_size, conf.index, conf.mode); break; } case QSEECOM_IOCTL_UNREGISTER_LISTENER_REQ: { if ((data->listener.id == 0) || (data->type != QSEECOM_LISTENER_SERVICE)) { Loading
include/crypto/ice.h +3 −1 Original line number Diff line number Diff line /* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -53,6 +53,8 @@ typedef void (*ice_error_cb)(void *, u32 error); struct qcom_ice_variant_ops *qcom_ice_get_variant_ops(struct device_node *node); struct platform_device *qcom_ice_get_pdevice(struct device_node *node); void qcom_ice_set_fde_flag(int flag); int qcom_ice_set_fde_conf(sector_t strt, sector_t size, int idx, int mode); #ifdef CONFIG_CRYPTO_DEV_QCOM_ICE int qcom_ice_setup_ice_hw(const char *storage_type, int enable); Loading
include/uapi/linux/qseecom.h +16 −0 Original line number Diff line number Diff line Loading @@ -277,6 +277,17 @@ struct qseecom_ce_info_req { struct qseecom_ce_pipe_entry ce_pipe_entry[MAX_CE_PIPE_PAIR_PER_UNIT]; }; struct qseecom_ice_data_t { int flag; }; struct qseecom_encdec_conf_t { __le64 start_sector; size_t fs_size; int index; int mode; }; #define SG_ENTRY_SZ sizeof(struct qseecom_sg_entry) #define SG_ENTRY_SZ_64BIT sizeof(struct qseecom_sg_entry_64bit) Loading Loading @@ -385,5 +396,10 @@ struct file; #define QSEECOM_IOCTL_QUERY_CE_PIPE_INFO \ _IOWR(QSEECOM_IOC_MAGIC, 42, struct qseecom_ce_info_req) #define QSEECOM_IOCTL_SET_ICE_INFO \ _IOWR(QSEECOM_IOC_MAGIC, 43, struct qseecom_ice_data_t) #define QSEECOM_IOCTL_SET_ENCDEC_INFO \ _IOWR(QSEECOM_IOC_MAGIC, 44, struct qseecom_encdec_conf_t) #endif /* _UAPI_QSEECOM_H_ */