xref: /rk3399_rockchip-uboot/lib/optee_clientApi/tee_mmc_rpmb.c (revision 6cef3c7b7cc45a9c882fc64e5496a416c99313b8)
1 /*
2  * Copyright 2024, Rockchip Electronics Co., Ltd
3  * hisping lin, <hisping.lin@rock-chips.com>
4  *
5  * SPDX-License-Identifier:	GPL-2.0+
6  */
7 #include <common.h>
8 #include <stdlib.h>
9 #include <command.h>
10 #include <mmc.h>
11 #include <optee_include/OpteeClientRPC.h>
12 #include <optee_include/tee_rpc.h>
13 #include <optee_include/tee_rpc_types.h>
14 #include <optee_include/teesmc_v2.h>
15 #include <optee_include/tee_client_api.h>
16 
17 /*
18  * Execute an RPMB storage operation.
19  */
20 #ifdef CONFIG_SUPPORT_EMMC_RPMB
21 
22 static int rpmb_data_req(struct s_rpmb *req_frm,
23 			 size_t req_nfrm,
24 			 struct s_rpmb *rsp_frm,
25 			 size_t rsp_nfrm)
26 {
27 	struct s_rpmb *req_packets = NULL;
28 	uint16_t req_type;
29 	int ret;
30 
31 	req_packets = memalign(CONFIG_SYS_CACHELINE_SIZE, sizeof(struct s_rpmb) * (req_nfrm + rsp_nfrm));
32 	if (!req_packets)
33 		return -1;
34 
35 	memcpy(req_packets, req_frm, sizeof(struct s_rpmb) * req_nfrm);
36 
37 	req_type = cpu_to_be16(req_packets->request);
38 
39 	switch (req_type) {
40 	case TEE_RPC_RPMB_MSG_TYPE_REQ_AUTH_KEY_PROGRAM: {
41 		ret = do_programkey(req_packets);
42 		break;
43 	}
44 	case TEE_RPC_RPMB_MSG_TYPE_REQ_WRITE_COUNTER_VAL_READ: {
45 		do_readcounter(req_packets);
46 		ret = TEEC_SUCCESS;
47 		break;
48 	}
49 	case TEE_RPC_RPMB_MSG_TYPE_REQ_AUTH_DATA_WRITE: {
50 		ret = do_authenticatedwrite(req_packets);
51 		break;
52 	}
53 	case TEE_RPC_RPMB_MSG_TYPE_REQ_AUTH_DATA_READ: {
54 		ret = do_authenticatedread(req_packets, rsp_nfrm);
55 		break;
56 	}
57 	default:
58 		ret = TEEC_ERROR_BAD_PARAMETERS;
59 		break;
60 	}
61 
62 	for (int i = 0; i < rsp_nfrm; i++)
63 		memcpy(rsp_frm + i, req_packets + i, sizeof(struct s_rpmb));
64 
65 	if (req_packets)
66 		free(req_packets);
67 
68 	return ret;
69 }
70 
71 static int rpmb_get_dev_info(struct tee_rpc_rpmb_dev_info *info)
72 {
73 	struct mmc *mmc;
74 	uint32_t cid_val[4];
75 
76 	mmc = do_returnmmc();
77 	if (!mmc)
78 		return -1;
79 
80 	for (int i = 0; i < 4; i++)
81 		cid_val[i] = cpu_to_be32(mmc->cid[i]);
82 
83 	memcpy(info->cid, cid_val, sizeof(info->cid));
84 
85 	info->rel_wr_sec_c = 1;
86 	info->rpmb_size_mult = (uint8_t)(mmc->capacity_rpmb / (128 * 1024));
87 	info->ret_code = 0;
88 
89 	return 0;
90 }
91 
92 TEEC_Result emmc_rpmb_process(t_teesmc32_arg *smc_arg)
93 {
94 	t_teesmc32_param *smc_param;
95 	struct tee_rpc_rpmb_cmd *rpmb_req;
96 	struct s_rpmb *req_packets = NULL;
97 	struct s_rpmb *rsp_packets = NULL;
98 	size_t req_num, rsp_num;
99 	struct tee_rpc_rpmb_dev_info *dev_info;
100 	TEEC_Result result = TEEC_SUCCESS;
101 	TEEC_Result status;
102 
103 	if (smc_arg->num_params != 2) {
104 		result = TEEC_ERROR_BAD_PARAMETERS;
105 		goto exit;
106 	}
107 
108 	smc_param = TEESMC32_GET_PARAMS(smc_arg);
109 	rpmb_req = (struct tee_rpc_rpmb_cmd *)(size_t)
110 		   smc_param[0].u.memref.buf_ptr;
111 
112 	switch (rpmb_req->cmd) {
113 	case TEE_RPC_RPMB_CMD_DATA_REQ: {
114 		req_packets = (struct s_rpmb *)(rpmb_req + 1);
115 		rsp_packets = (struct s_rpmb *)(size_t)smc_param[1].u.memref.buf_ptr;
116 		req_num = cpu_to_be16(req_packets->block_count);
117 		req_num = (req_num == 0 ? 1 : req_num);
118 		rsp_num = (rpmb_req->block_count == 0 ? 1 : rpmb_req->block_count);
119 
120 		status = rpmb_data_req(req_packets, req_num, rsp_packets, rsp_num);
121 		if (status != 0)
122 			result = TEEC_ERROR_GENERIC;
123 		goto exit;
124 	}
125 	case TEE_RPC_RPMB_CMD_GET_DEV_INFO: {
126 		dev_info = (struct tee_rpc_rpmb_dev_info *)
127 			   (size_t)smc_param[1].u.memref.buf_ptr;
128 
129 		status = rpmb_get_dev_info(dev_info);
130 		if (status != 0)
131 			result = TEEC_ERROR_GENERIC;
132 		goto exit;
133 	}
134 	default:
135 		result = TEEC_ERROR_BAD_PARAMETERS;
136 		goto exit;
137 	}
138 
139 exit:
140 	smc_arg->ret = result;
141 	smc_arg->ret_origin = TEEC_ORIGIN_API;
142 
143 	return result;
144 }
145 
146 #else
147 
148 TEEC_Result emmc_rpmb_process(t_teesmc32_arg *smc_arg)
149 {
150 	smc_arg = smc_arg;
151 	return TEEC_ERROR_NOT_IMPLEMENTED;
152 }
153 
154 #endif
155