platform: msm_shared: Add support for secure write protect for UFS
Add support for secure write protect for UFS.
Change-Id: If550cfe9b17ee6917a5206d81af69834690a25f6
diff --git a/include/km_main.h b/include/km_main.h
index 42920d1..fa606ad 100644
--- a/include/km_main.h
+++ b/include/km_main.h
@@ -67,6 +67,7 @@
KEYMASTER_READ_LK_DEVICE_STATE = (KEYMASTER_UTILS_CMD_ID + 2UL),
KEYMASTER_WRITE_LK_DEVICE_STATE = (KEYMASTER_UTILS_CMD_ID + 3UL),
KEYMASTER_MILESTONE_CALL = (KEYMASTER_UTILS_CMD_ID + 4UL),
+ KEYMASTER_SECURE_WRITE_PROTECT = (KEYMASTER_UTILS_CMD_ID + 6UL),
KEYMASTER_LAST_CMD_ENTRY = (int)0xFFFFFFFFULL
} keymaster_cmd_t;
@@ -163,4 +164,45 @@
int status;
}__attribute__ ((packed)) key_op_delete_all_rsp_t;
+typedef enum _secure_write_prot_op_t
+{
+ SWP_READ_CONFIG,
+ SWP_WRITE_CONFIG,
+ SWP_LAST_CMD_ENTRY = (int)0xFFFFFFFFULL
+} secure_write_prot_op_t;
+
+/*
+ @brief
+ Data structure
+
+ @param[in] cmd_id Command ID of the request
+ @param[in] op Secure write protect operation (enum from secure_write_prot_op_t)
+ @param[in] swp_write_data_offset Offset of data for SWP operation
+ @param[in] swp_write_data_len Length of data for SWP operation
+*/
+
+typedef struct _secure_write_prot_req_t
+{
+ uint32 cmd_id;
+ uint32 op;
+ uint32 swp_write_data_offset;
+ uint32 swp_write_data_len;
+}__attribute__((packed)) secure_write_prot_req_t;
+
+/*
+ @brief
+ Data structure
+
+ @param[out] status Status of the request
+ @param[out] swp_read_data_offset Offset of data for SWP operation
+ @param[out] swp_read_data_len Length of data for SWP operation
+*/
+
+typedef struct _secure_write_prot_rsp_t
+{
+ int status;
+ uint32 swp_read_data_offset;
+ uint32 swp_read_data_len;
+}__attribute__((packed)) secure_write_prot_rsp_t;
+
#endif /* KM_MAIN_H */
diff --git a/platform/msm_shared/include/rpmb.h b/platform/msm_shared/include/rpmb.h
index 8e9f148..265a0d6 100644
--- a/platform/msm_shared/include/rpmb.h
+++ b/platform/msm_shared/include/rpmb.h
@@ -97,6 +97,23 @@
uint32_t dev_type;
};
+/* Secure Write Protect Info Entry structure */
+typedef struct
+{
+ uint8_t wp_enable; /* UFS: WPF (Write Protect Flag), eMMC: SECURE_WP_MODE_ENABLE */
+ uint8_t wp_type_mask; /* UFS: WPT (Write Protect Type), eMMC: SECURE_WP_MODE_CONFIG */
+ uint64_t addr; /* UFS: LBA, eMMC: 0x1/0x2 (address of the device config register) */
+ uint32_t num_blocks; /* UFS: Num LBA, eMMC: Set to 0 */
+} __attribute__ ((packed)) qsee_stor_secure_wp_info_entry_t;
+
+/* Secure Write Protect Info structure */
+typedef struct
+{
+ uint8_t lun_number; /* UFS: LUN #, eMMC: Set to 0 */
+ uint8_t num_entries; /* Number of Secure wp entries */
+ qsee_stor_secure_wp_info_entry_t wp_entries[4]; /* Max 4 entries total */
+} __attribute__ ((packed)) qsee_stor_secure_wp_info_t;
+
/* dump a given RPMB frame */
static inline void dump_rpmb_frame(uint8_t *frame, const char *frame_type)
{
@@ -136,4 +153,6 @@
int rpmb_write(uint32_t *req_buf, uint32_t blk_cnt, uint32_t rel_wr_count, uint32_t *resp_buf, uint32_t *resp_len);
int rpmb_read(uint32_t *req_buf, uint32_t blk_cnt, uint32_t *resp_buf, uint32_t *resp_len);
struct rpmb_init_info *rpmb_get_init_info();
+/* RPMB API to set secure write protect configuration block */
+int swp_write(qsee_stor_secure_wp_info_t swp_cb);
#endif
diff --git a/platform/msm_shared/rpmb/rpmb.c b/platform/msm_shared/rpmb/rpmb.c
index e0c94d3..3c85b8d 100644
--- a/platform/msm_shared/rpmb/rpmb.c
+++ b/platform/msm_shared/rpmb/rpmb.c
@@ -25,8 +25,11 @@
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <stdlib.h>
+#include <string.h>
#include <platform.h>
#include <rpmb.h>
+#include <km_main.h>
#include <rpmb_listener.h>
#include <mmc_sdhci.h>
#include <boot_device.h>
@@ -177,6 +180,35 @@
return 0;
}
+/*
+ * SWP Write function is used to send a configuration block to rpmb
+ * for enabling a secure write protect based on LBAs. This function
+ * should is enabled by the keymaster secure app and this function
+ * can only be called before we send the milestone call to keymaster.
+ */
+int swp_write(qsee_stor_secure_wp_info_t swp_cb)
+{
+ secure_write_prot_req_t *req;
+ secure_write_prot_rsp_t rsp;
+ int ret = 0;
+ uint32_t tlen = sizeof(secure_write_prot_req_t) + sizeof(swp_cb);
+ if(!(req = (secure_write_prot_req_t *) malloc(tlen)))
+ ASSERT(0);
+ void *cpy_ptr = (uint8_t *) req + sizeof(secure_write_prot_req_t);
+ req->cmd_id = KEYMASTER_SECURE_WRITE_PROTECT;
+ req->op = SWP_WRITE_CONFIG;
+ req->swp_write_data_offset = sizeof(secure_write_prot_req_t);
+ req->swp_write_data_len = sizeof(swp_cb);
+ memcpy(cpy_ptr, (void *)&swp_cb, sizeof(swp_cb));
+ ret = qseecom_send_command(get_secapp_handle(), (void *)req, tlen, (void *)&rsp, sizeof(rsp));
+ if(ret < 0 || rsp.status < 0)
+ {
+ dprintf(CRITICAL, "Setting secure write protect configuration failed\n");
+ return -1;
+ }
+ return 0;
+}
+
int rpmb_uninit()
{
int ret = 0;