1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2021 Rockchip Electronics Co. Ltd.
4 */
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <strings.h>
9 #include <rktest_ta.h>
10 #include <rktest.h>
11
12
13 const TEEC_UUID UUID = RKTEST_TA_UUID;
14
invoke_transfer_data(TEEC_Context * context,TEEC_Session * session,TEEC_Operation * operation,uint32_t * error_origin)15 static TEEC_Result invoke_transfer_data(TEEC_Context *context, TEEC_Session *session,
16 TEEC_Operation *operation, uint32_t *error_origin)
17 {
18 TEEC_Result res = TEEC_SUCCESS;
19 TEEC_SharedMemory sm;
20 uint8_t temref_input[50];
21 const uint8_t transfer_inout[] = "Transfer data test.";
22
23 memcpy(temref_input, transfer_inout, sizeof(transfer_inout));
24 //Initialize the Shared Memory buffers
25 sm.size = sizeof(temref_input);
26 sm.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
27
28 res = TEEC_AllocateSharedMemory(context, &sm);
29 if (res != TEEC_SUCCESS) {
30 printf("AllocateSharedMemory ERR! res= 0x%x\n", res);
31 return res;
32 }
33
34 memset(operation, 0, sizeof(TEEC_Operation));
35 //Note: these parameters must correspond to operation.params[],
36 operation->paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_TEMP_INPUT,
37 TEEC_MEMREF_PARTIAL_OUTPUT, TEEC_NONE);
38 operation->params[0].value.a = 66;
39 //This buffer will be temporarily shared.
40 operation->params[1].tmpref.size = sizeof(temref_input);
41 operation->params[1].tmpref.buffer = (void *)temref_input;
42 operation->params[2].memref.parent = &sm;
43 operation->params[2].memref.offset = 0;
44 operation->params[2].memref.size = sm.size;
45
46 //Invoke to TA
47 res = TEEC_InvokeCommand(session, RKTEST_TA_CMD_TRANSFER_DATA,
48 operation, error_origin);
49 if (res != TEEC_SUCCESS) {
50 printf("InvokeCommand ERR! res= 0x%x\n", res);
51 goto out;
52 }
53
54 //Check the result
55 if (operation->params[0].value.a == 66+1 &&
56 operation->params[0].value.b == operation->params[0].value.a)
57 printf("test value : Pass!\n");
58 else
59 printf("test value : Fail! (mismatch values)\n");
60
61 //Check if the sm->buffer (params[2]) = TRANSFER_INOUT (params[1])
62 if (memcmp(sm.buffer, transfer_inout, sizeof(transfer_inout)) == 0)
63 printf("test buffer : Pass!\n");
64 else
65 printf("test buffer : Fail! (mismatch buffer)\n");
66
67 out:
68 TEEC_ReleaseSharedMemory(&sm);
69 return res;
70 };
71
invoke_storage(TEEC_Session * session,TEEC_Operation * operation,uint32_t * error_origin)72 static TEEC_Result invoke_storage(TEEC_Session *session,
73 TEEC_Operation *operation, uint32_t *error_origin)
74 {
75 return TEEC_InvokeCommand(session, RKTEST_TA_CMD_STORAGE,
76 operation, error_origin);
77 };
78
test_storage_speed(TEEC_Session * session,TEEC_Operation * operation,uint32_t * error_origin,uint32_t storage_type,uint32_t * storage_size,uint32_t times)79 static TEEC_Result test_storage_speed(TEEC_Session *session,
80 TEEC_Operation *operation, uint32_t *error_origin,
81 uint32_t storage_type, uint32_t *storage_size, uint32_t times)
82 {
83 TEEC_Result res = TEEC_SUCCESS;
84 uint8_t *temref_input = NULL;
85
86 for (uint32_t i = 0; i < times; i++) {
87 temref_input = malloc(storage_size[i]);
88 memset(temref_input, 0xab, storage_size[i]);
89 memset(operation, 0, sizeof(TEEC_Operation));
90
91 //Note: these parameters must correspond to operation.params[],
92 operation->paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INOUT, TEEC_VALUE_INPUT,
93 TEEC_NONE, TEEC_NONE);
94 operation->params[0].tmpref.size = storage_size[i];
95 operation->params[0].tmpref.buffer = (void *)temref_input;
96 operation->params[1].value.a = storage_type;
97
98 //Invoke to TA
99 res = TEEC_InvokeCommand(session, RKTEST_TA_CMD_STORAGE_SPEED,
100 operation, error_origin);
101
102 if (temref_input)
103 free(temref_input);
104
105 if (res != TEEC_SUCCESS) {
106 printf("InvokeCommand ERR! res= 0x%x\n", res);
107 break;
108 }
109 }
110
111 return res;
112 };
113
invoke_storage_speed(TEEC_Session * session,TEEC_Operation * operation,uint32_t * error_origin)114 static TEEC_Result invoke_storage_speed(TEEC_Session *session,
115 TEEC_Operation *operation, uint32_t *error_origin)
116 {
117 TEEC_Result res = TEEC_SUCCESS;
118 uint32_t rpmb_storage_size[] = {32, 1024, 4096, 30000};
119 uint32_t ree_storage_size[] = {32, 1024, 4096, 30000, 60000};
120
121 res = test_storage_speed(session, operation, error_origin, TEE_STORAGE_PRIVATE_RPMB,
122 rpmb_storage_size, sizeof(rpmb_storage_size) / sizeof(rpmb_storage_size[0]));
123 if (res != TEEC_SUCCESS)
124 return res;
125
126 res = test_storage_speed(session, operation, error_origin, TEE_STORAGE_PRIVATE_REE,
127 ree_storage_size, sizeof(ree_storage_size) / sizeof(ree_storage_size[0]));
128 return res;
129 }
130
invoke_property(TEEC_Session * session,TEEC_Operation * operation,uint32_t * error_origin)131 static TEEC_Result invoke_property(TEEC_Session *session,
132 TEEC_Operation *operation, uint32_t *error_origin)
133 {
134 return TEEC_InvokeCommand(session, RKTEST_TA_CMD_PROPERTY,
135 operation, error_origin);
136 };
137
invoke_crypto_sha(TEEC_Session * session,TEEC_Operation * operation,uint32_t * error_origin)138 static TEEC_Result invoke_crypto_sha(TEEC_Session *session,
139 TEEC_Operation *operation, uint32_t *error_origin)
140 {
141 return TEEC_InvokeCommand(session, RKTEST_TA_CMD_CRYPTO_SHA,
142 operation, error_origin);
143 };
144
invoke_crypto_aes(TEEC_Session * session,TEEC_Operation * operation,uint32_t * error_origin)145 static TEEC_Result invoke_crypto_aes(TEEC_Session *session,
146 TEEC_Operation *operation, uint32_t *error_origin)
147 {
148 return TEEC_InvokeCommand(session, RKTEST_TA_CMD_CRYPTO_AES,
149 operation, error_origin);
150 };
151
invoke_crypto_rsa(TEEC_Session * session,TEEC_Operation * operation,uint32_t * error_origin)152 static TEEC_Result invoke_crypto_rsa(TEEC_Session *session,
153 TEEC_Operation *operation, uint32_t *error_origin)
154 {
155 return TEEC_InvokeCommand(session, RKTEST_TA_CMD_CRYPTO_RSA,
156 operation, error_origin);
157 };
158
invoke_otp_read(TEEC_Session * session,TEEC_Operation * operation,uint32_t * error_origin)159 static TEEC_Result invoke_otp_read(TEEC_Session *session,
160 TEEC_Operation *operation, uint32_t *error_origin)
161 {
162 return TEEC_InvokeCommand(session, RKTEST_TA_CMD_OEM_OTP_READ,
163 operation, error_origin);
164 };
165
invoke_otp_write(TEEC_Session * session,TEEC_Operation * operation,uint32_t * error_origin)166 static TEEC_Result invoke_otp_write(TEEC_Session *session,
167 TEEC_Operation *operation, uint32_t *error_origin)
168 {
169 return TEEC_InvokeCommand(session, RKTEST_TA_CMD_OEM_OTP_WRITE,
170 operation, error_origin);
171 };
172
invoke_otp_size(TEEC_Session * session,TEEC_Operation * operation,uint32_t * error_origin)173 static TEEC_Result invoke_otp_size(TEEC_Session *session,
174 TEEC_Operation *operation, uint32_t *error_origin)
175 {
176 return TEEC_InvokeCommand(session, RKTEST_TA_CMD_OEM_OTP_SIZE,
177 operation, error_origin);
178 };
179
invoke_trng_read(TEEC_Session * session,TEEC_Operation * operation,uint32_t * error_origin)180 static TEEC_Result invoke_trng_read(TEEC_Session *session,
181 TEEC_Operation *operation, uint32_t *error_origin)
182 {
183 return TEEC_InvokeCommand(session, RKTEST_TA_CMD_TRNG_READ,
184 operation, error_origin);
185 }
186
rk_test(uint32_t invoke_command)187 TEEC_Result rk_test(uint32_t invoke_command)
188 {
189 TEEC_Result res = TEEC_SUCCESS;
190 uint32_t error_origin = 0;
191 TEEC_Context contex;
192 TEEC_Session session;
193 TEEC_Operation operation;
194
195 //[1] Connect to TEE
196 res = TEEC_InitializeContext(NULL, &contex);
197 if (res != TEEC_SUCCESS) {
198 printf("TEEC_InitializeContext failed with code 0x%x\n", res);
199 return res;
200 }
201
202 //[2] Open session with TEE application
203 res = TEEC_OpenSession(&contex, &session, &UUID,
204 TEEC_LOGIN_PUBLIC, NULL, NULL, &error_origin);
205 if (res != TEEC_SUCCESS) {
206 printf("TEEC_Opensession failed with code 0x%x origin 0x%x\n",
207 res, error_origin);
208 goto out;
209 }
210
211 //[3] Perform operation initialization
212 memset(&operation, 0, sizeof(TEEC_Operation));
213 operation.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE,
214 TEEC_NONE, TEEC_NONE);
215
216 //[4] Start invoke command to the TEE application.
217 switch (invoke_command) {
218 case TRANSFER_DATA:
219 res = invoke_transfer_data(&contex, &session, &operation, &error_origin);
220 break;
221 case STORAGE:
222 res = invoke_storage(&session, &operation, &error_origin);
223 break;
224 case STORAGE_SPEED:
225 res = invoke_storage_speed(&session, &operation, &error_origin);
226 break;
227 case PROPERTY:
228 res = invoke_property(&session, &operation, &error_origin);
229 break;
230 case CRYPTO_SHA:
231 res = invoke_crypto_sha(&session, &operation, &error_origin);
232 break;
233 case CRYPTO_AES:
234 res = invoke_crypto_aes(&session, &operation, &error_origin);
235 break;
236 case CRYPTO_RSA:
237 res = invoke_crypto_rsa(&session, &operation, &error_origin);
238 break;
239 case OTP_READ:
240 res = invoke_otp_read(&session, &operation, &error_origin);
241 break;
242 case OTP_WRITE:
243 res = invoke_otp_write(&session, &operation, &error_origin);
244 break;
245 case OTP_SIZE:
246 res = invoke_otp_size(&session, &operation, &error_origin);
247 case TRNG_READ:
248 res = invoke_trng_read(&session, &operation, &error_origin);
249 break;
250 default:
251 printf("Doing nothing.\n");
252 break;
253 }
254 if (res != TEEC_SUCCESS) {
255 printf("Test ERR. res 0x%x origin 0x%x\n", res, error_origin);
256 goto out1;
257 }
258 printf("Test OK.\n");
259 //[5] Tidyup resources
260 out1:
261 TEEC_CloseSession(&session);
262 out:
263 TEEC_FinalizeContext(&contex);
264 return res;
265 }
266
267