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