xref: /rk3399_rockchip-uboot/lib/optee_clientApi/OpteeClientInterface.c (revision d9da4b44281a549e13a5f3a136d1ffc16cd52f57)
1 /*
2  * Copyright 2017, Rockchip Electronics Co., Ltd
3  * hisping lin, <hisping.lin@rock-chips.com>
4  *
5  * SPDX-License-Identifier:	GPL-2.0+
6  */
7 
8 #include <common.h>
9 #include <optee_include/OpteeClientInterface.h>
10 #include <optee_include/OpteeClientApiLib.h>
11 #include <optee_include/tee_client_api.h>
12 #include <optee_include/tee_api_defines.h>
13 #include <boot_rkimg.h>
14 #include <stdlib.h>
15 #include <attestation_key.h>
16 
17 #define	BOOT_FROM_EMMC	(1 << 1)
18 #define STORAGE_CMD_READ_ATTRIBUTE_HASH		0
19 #define STORAGE_CMD_WRITE_ATTRIBUTE_HASH	1
20 #define STORAGE_CMD_UBOOT_END_OTP		2
21 #define STORAGE_CMD_READ_VBOOTKEY_HASH		3
22 #define STORAGE_CMD_WRITE_VBOOTKEY_HASH		4
23 #define STORAGE_CMD_READ_ENABLE_FLAG		5
24 #define STORAGE_CMD_WRITE_TA_ENCRYPTION_KEY	9
25 #define STORAGE_CMD_CHECK_SECURITY_LEVEL_FLAG	10
26 #define STORAGE_CMD_WRITE_OEM_HUK		11
27 #define STORAGE_CMD_WRITE_OEM_NS_OTP		12
28 #define STORAGE_CMD_READ_OEM_NS_OTP		13
29 #define STORAGE_CMD_WRITE_OEM_HR_OTP		14
30 #define STORAGE_CMD_SET_OEM_HR_OTP_READ_LOCK	15
31 
32 static uint8_t b2hs_add_base(uint8_t in)
33 {
34 	if (in > 9)
35 		return in + 55;
36 	else
37 		return in + 48;
38 }
39 
40 static uint32_t b2hs(uint8_t *b, uint8_t *hs, uint32_t blen, uint32_t hslen)
41 {
42 	uint32_t i = 0;
43 
44 	if (blen * 2 + 1 > hslen)
45 		return 0;
46 
47 	for (; i < blen; i++) {
48 		hs[i * 2 + 1] = b2hs_add_base(b[i] & 0xf);
49 		hs[i * 2] = b2hs_add_base(b[i] >> 4);
50 	}
51 	hs[blen * 2] = 0;
52 
53 	return blen * 2;
54 }
55 
56 static uint32_t trusty_base_write_security_data(char *filename,
57 						uint32_t filename_size,
58 						uint8_t *data,
59 						uint32_t data_size)
60 {
61 	TEEC_Result TeecResult;
62 	TEEC_Context TeecContext;
63 	TEEC_Session TeecSession;
64 	uint32_t ErrorOrigin;
65 	TEEC_UUID tempuuid = { 0x1b484ea5, 0x698b, 0x4142,
66 		{ 0x82, 0xb8, 0x3a, 0xcf, 0x16, 0xe9, 0x9e, 0x2a } };
67 	TEEC_UUID *TeecUuid = &tempuuid;
68 	TEEC_Operation TeecOperation = {0};
69 	struct blk_desc *dev_desc;
70 	dev_desc = rockchip_get_bootdev();
71 	if (!dev_desc) {
72 		printf("%s: dev_desc is NULL!\n", __func__);
73 		return -TEEC_ERROR_GENERIC;
74 	}
75 
76 	TeecResult = OpteeClientApiLibInitialize();
77 	if (TeecResult != TEEC_SUCCESS)
78 		return TeecResult;
79 
80 	TeecResult = TEEC_InitializeContext(NULL, &TeecContext);
81 	if (TeecResult != TEEC_SUCCESS)
82 		return TeecResult;
83 
84 	TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
85 						    TEEC_NONE,
86 						    TEEC_NONE,
87 						    TEEC_NONE);
88 	/*0 nand or emmc "security" partition , 1 rpmb*/
89 	if (dev_desc->if_type == IF_TYPE_MMC && dev_desc->devnum == 0)
90 		TeecOperation.params[0].value.a = 1;
91 	else
92 		TeecOperation.params[0].value.a = 0;
93 #ifdef CONFIG_OPTEE_ALWAYS_USE_SECURITY_PARTITION
94 	TeecOperation.params[0].value.a = 0;
95 #endif
96 
97 	TeecResult = TEEC_OpenSession(&TeecContext,
98 				&TeecSession,
99 				TeecUuid,
100 				TEEC_LOGIN_PUBLIC,
101 				NULL,
102 				&TeecOperation,
103 				&ErrorOrigin);
104 	if (TeecResult != TEEC_SUCCESS)
105 		return TeecResult;
106 
107 	TEEC_SharedMemory SharedMem0 = {0};
108 
109 	SharedMem0.size = filename_size;
110 	SharedMem0.flags = 0;
111 
112 	TeecResult = TEEC_AllocateSharedMemory(&TeecContext, &SharedMem0);
113 	if (TeecResult != TEEC_SUCCESS)
114 		goto exit;
115 
116 	memcpy(SharedMem0.buffer, filename, SharedMem0.size);
117 
118 	TEEC_SharedMemory SharedMem1 = {0};
119 
120 	SharedMem1.size = data_size;
121 	SharedMem1.flags = 0;
122 
123 	TeecResult = TEEC_AllocateSharedMemory(&TeecContext, &SharedMem1);
124 	if (TeecResult != TEEC_SUCCESS)
125 		goto exit;
126 
127 	memcpy(SharedMem1.buffer, data, SharedMem1.size);
128 
129 	TeecOperation.params[0].tmpref.buffer = SharedMem0.buffer;
130 	TeecOperation.params[0].tmpref.size = SharedMem0.size;
131 
132 	TeecOperation.params[1].tmpref.buffer = SharedMem1.buffer;
133 	TeecOperation.params[1].tmpref.size = SharedMem1.size;
134 
135 
136 	TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
137 						TEEC_MEMREF_TEMP_INOUT,
138 						TEEC_NONE,
139 						TEEC_NONE);
140 
141 	TeecResult = TEEC_InvokeCommand(&TeecSession,
142 					1,
143 					&TeecOperation,
144 					&ErrorOrigin);
145 	if (TeecResult != TEEC_SUCCESS)
146 		goto exit;
147 exit:
148 	TEEC_ReleaseSharedMemory(&SharedMem0);
149 	TEEC_ReleaseSharedMemory(&SharedMem1);
150 	TEEC_CloseSession(&TeecSession);
151 	TEEC_FinalizeContext(&TeecContext);
152 
153 	return TeecResult;
154 }
155 
156 static uint32_t trusty_base_read_security_data(char *filename,
157 					       uint32_t filename_size,
158 					       uint8_t *data,
159 					       uint32_t data_size)
160 {
161 	TEEC_Result TeecResult;
162 	TEEC_Context TeecContext;
163 	TEEC_Session TeecSession;
164 	uint32_t ErrorOrigin;
165 	TEEC_UUID tempuuid = { 0x1b484ea5, 0x698b, 0x4142,
166 			{ 0x82, 0xb8, 0x3a, 0xcf, 0x16, 0xe9, 0x9e, 0x2a } };
167 	TEEC_UUID *TeecUuid = &tempuuid;
168 	TEEC_Operation TeecOperation = {0};
169 
170 	struct blk_desc *dev_desc;
171 	dev_desc = rockchip_get_bootdev();
172 	if (!dev_desc) {
173 		printf("%s: dev_desc is NULL!\n", __func__);
174 		return -TEEC_ERROR_GENERIC;
175 	}
176 
177 	TeecResult = OpteeClientApiLibInitialize();
178 	if (TeecResult != TEEC_SUCCESS)
179 		return TeecResult;
180 
181 	TeecResult = TEEC_InitializeContext(NULL, &TeecContext);
182 	if (TeecResult != TEEC_SUCCESS)
183 		return TeecResult;
184 
185 	TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
186 						TEEC_NONE,
187 						TEEC_NONE,
188 						TEEC_NONE);
189 	/*0 nand or emmc "security" partition , 1 rpmb*/
190 	if (dev_desc->if_type == IF_TYPE_MMC && dev_desc->devnum == 0)
191 		TeecOperation.params[0].value.a = 1;
192 	else
193 		TeecOperation.params[0].value.a = 0;
194 #ifdef CONFIG_OPTEE_ALWAYS_USE_SECURITY_PARTITION
195 	TeecOperation.params[0].value.a = 0;
196 #endif
197 
198 	TeecResult = TEEC_OpenSession(&TeecContext,
199 				&TeecSession,
200 				TeecUuid,
201 				TEEC_LOGIN_PUBLIC,
202 				NULL,
203 				&TeecOperation,
204 				&ErrorOrigin);
205 	if (TeecResult != TEEC_SUCCESS)
206 		return TeecResult;
207 
208 	TEEC_SharedMemory SharedMem0 = {0};
209 
210 	SharedMem0.size = filename_size;
211 	SharedMem0.flags = 0;
212 
213 	TeecResult = TEEC_AllocateSharedMemory(&TeecContext, &SharedMem0);
214 	if (TeecResult != TEEC_SUCCESS)
215 		goto exit;
216 
217 	memcpy(SharedMem0.buffer, filename, SharedMem0.size);
218 
219 	TEEC_SharedMemory SharedMem1 = {0};
220 
221 	SharedMem1.size = data_size;
222 	SharedMem1.flags = 0;
223 
224 	TeecResult = TEEC_AllocateSharedMemory(&TeecContext, &SharedMem1);
225 	if (TeecResult != TEEC_SUCCESS)
226 		goto exit;
227 
228 	TeecOperation.params[0].tmpref.buffer = SharedMem0.buffer;
229 	TeecOperation.params[0].tmpref.size = SharedMem0.size;
230 
231 	TeecOperation.params[1].tmpref.buffer = SharedMem1.buffer;
232 	TeecOperation.params[1].tmpref.size = SharedMem1.size;
233 
234 	TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
235 						TEEC_MEMREF_TEMP_INOUT,
236 						TEEC_NONE,
237 						TEEC_NONE);
238 
239 	TeecResult = TEEC_InvokeCommand(&TeecSession,
240 					0,
241 					&TeecOperation,
242 					&ErrorOrigin);
243 	if (TeecResult == TEEC_SUCCESS)
244 		memcpy(data, SharedMem1.buffer, SharedMem1.size);
245 exit:
246 	TEEC_ReleaseSharedMemory(&SharedMem0);
247 	TEEC_ReleaseSharedMemory(&SharedMem1);
248 	TEEC_CloseSession(&TeecSession);
249 	TEEC_FinalizeContext(&TeecContext);
250 
251 	return TeecResult;
252 }
253 
254 static uint32_t trusty_base_end_security_data(void)
255 {
256 	TEEC_Result TeecResult;
257 	TEEC_Context TeecContext;
258 	TEEC_Session TeecSession;
259 	uint32_t ErrorOrigin;
260 	TEEC_UUID  tempuuid = { 0x1b484ea5, 0x698b, 0x4142,
261 		{ 0x82, 0xb8, 0x3a, 0xcf, 0x16, 0xe9, 0x9e, 0x2a } };
262 	TEEC_UUID *TeecUuid = &tempuuid;
263 	TEEC_Operation TeecOperation = {0};
264 
265 	TeecResult = OpteeClientApiLibInitialize();
266 	if (TeecResult != TEEC_SUCCESS)
267 		return TeecResult;
268 
269 	TeecResult = TEEC_InitializeContext(NULL, &TeecContext);
270 	if (TeecResult != TEEC_SUCCESS)
271 		return TeecResult;
272 
273 	TeecResult = TEEC_OpenSession(&TeecContext,
274 				&TeecSession,
275 				TeecUuid,
276 				TEEC_LOGIN_PUBLIC,
277 				NULL,
278 				NULL,
279 				&ErrorOrigin);
280 	if (TeecResult != TEEC_SUCCESS)
281 		return TeecResult;
282 
283 	TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE,
284 						    TEEC_NONE,
285 						    TEEC_NONE,
286 						    TEEC_NONE);
287 
288 	TeecResult = TEEC_InvokeCommand(&TeecSession,
289 					2,
290 					&TeecOperation,
291 					&ErrorOrigin);
292 	if (TeecResult != TEEC_SUCCESS)
293 		goto exit;
294 exit:
295 	TEEC_CloseSession(&TeecSession);
296 	TEEC_FinalizeContext(&TeecContext);
297 
298 	return TeecResult;
299 }
300 
301 uint32_t trusty_read_rollback_index(uint32_t slot, uint64_t *value)
302 {
303 	char hs[9];
304 
305 	b2hs((uint8_t *)&slot, (uint8_t *)hs, 4, 9);
306 
307 	return trusty_base_read_security_data(hs, 8, (uint8_t *)value, 8);
308 }
309 
310 uint32_t trusty_write_rollback_index(uint32_t slot, uint64_t value)
311 {
312 	char hs[9];
313 
314 	b2hs((uint8_t *)&slot, (uint8_t *)hs, 4, 9);
315 
316 	return trusty_base_write_security_data(hs, 8, (uint8_t *)&value, 8);
317 }
318 
319 uint32_t trusty_read_permanent_attributes(uint8_t *attributes, uint32_t size)
320 {
321 	return trusty_base_read_security_data("attributes",
322 		sizeof("attributes"), attributes, size);
323 }
324 
325 uint32_t trusty_write_permanent_attributes(uint8_t *attributes, uint32_t size)
326 {
327 	return trusty_base_write_security_data("attributes",
328 		sizeof("attributes"), attributes, size);
329 }
330 
331 uint32_t trusty_read_permanent_attributes_flag(uint8_t *attributes)
332 {
333 	return trusty_base_read_security_data("attributes_flag",
334 		sizeof("attributes_flag"), attributes, 1);
335 }
336 
337 uint32_t trusty_write_permanent_attributes_flag(uint8_t attributes)
338 {
339 	return trusty_base_write_security_data("attributes_flag",
340 		sizeof("attributes_flag"), &attributes, 1);
341 }
342 
343 uint32_t trusty_read_permanent_attributes_cer(uint8_t *attributes,
344 					      uint32_t size)
345 {
346 	return trusty_base_read_security_data("rsacer",
347 		sizeof("rsacer"), attributes, size);
348 }
349 
350 uint32_t trusty_write_permanent_attributes_cer(uint8_t *attributes,
351 					       uint32_t size)
352 {
353 	return trusty_base_write_security_data("rsacer",
354 		sizeof("rsacer"), attributes, size);
355 }
356 
357 uint32_t trusty_read_lock_state(uint8_t *lock_state)
358 {
359 	return trusty_base_read_security_data("lock_state",
360 		sizeof("lock_state"), lock_state, 1);
361 }
362 
363 uint32_t trusty_write_lock_state(uint8_t lock_state)
364 {
365 	return trusty_base_write_security_data("lock_state",
366 		sizeof("lock_state"), &lock_state, 1);
367 }
368 
369 uint32_t trusty_read_flash_lock_state(uint8_t *flash_lock_state)
370 {
371 	return trusty_base_read_security_data("flash_lock_state",
372 		sizeof("flash_lock_state"), flash_lock_state, 1);
373 }
374 
375 uint32_t trusty_write_flash_lock_state(uint8_t flash_lock_state)
376 {
377 	return trusty_base_write_security_data("flash_lock_state",
378 		sizeof("flash_lock_state"), &flash_lock_state, 1);
379 }
380 
381 static uint32_t trusty_base_end_efuse_or_otp(void)
382 {
383 	TEEC_Result TeecResult;
384 	TEEC_Context TeecContext;
385 	TEEC_Session TeecSession;
386 	uint32_t ErrorOrigin;
387 	TEEC_UUID tempuuid = { 0x2d26d8a8, 0x5134, 0x4dd8,
388 			{ 0xb3, 0x2f, 0xb3, 0x4b, 0xce, 0xeb, 0xc4, 0x71 } };
389 
390 	TEEC_UUID *TeecUuid = &tempuuid;
391 	TEEC_Operation TeecOperation = {0};
392 
393 	TeecResult = OpteeClientApiLibInitialize();
394 	if (TeecResult != TEEC_SUCCESS)
395 		return TeecResult;
396 
397 	TeecResult = TEEC_InitializeContext(NULL, &TeecContext);
398 	if (TeecResult != TEEC_SUCCESS)
399 		return TeecResult;
400 
401 	TeecResult = TEEC_OpenSession(&TeecContext,
402 				      &TeecSession,
403 				      TeecUuid,
404 				      TEEC_LOGIN_PUBLIC,
405 				      NULL,
406 				      NULL,
407 				      &ErrorOrigin);
408 	if (TeecResult != TEEC_SUCCESS)
409 		return TeecResult;
410 
411 	TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE,
412 						    TEEC_NONE,
413 						    TEEC_NONE,
414 						    TEEC_NONE);
415 
416 	TeecResult = TEEC_InvokeCommand(&TeecSession,
417 					STORAGE_CMD_UBOOT_END_OTP,
418 					&TeecOperation,
419 					&ErrorOrigin);
420 	if (TeecResult != TEEC_SUCCESS)
421 		goto exit;
422 exit:
423 	TEEC_CloseSession(&TeecSession);
424 	TEEC_FinalizeContext(&TeecContext);
425 
426 	return TeecResult;
427 }
428 
429 static uint32_t trusty_base_efuse_or_otp_operation(uint32_t cmd,
430 						   uint8_t is_write,
431 						   uint32_t *buf,
432 						   uint32_t length)
433 {
434 	TEEC_Result TeecResult;
435 	TEEC_Context TeecContext;
436 	TEEC_Session TeecSession;
437 	uint32_t ErrorOrigin;
438 
439 	TEEC_UUID tempuuid = { 0x2d26d8a8, 0x5134, 0x4dd8,
440 			{ 0xb3, 0x2f, 0xb3, 0x4b, 0xce, 0xeb, 0xc4, 0x71 } };
441 	TEEC_UUID *TeecUuid = &tempuuid;
442 	TEEC_Operation TeecOperation = {0};
443 
444 	TeecResult = OpteeClientApiLibInitialize();
445 	if (TeecResult != TEEC_SUCCESS)
446 		return TeecResult;
447 
448 	TeecResult = TEEC_InitializeContext(NULL, &TeecContext);
449 	if (TeecResult != TEEC_SUCCESS)
450 		return TeecResult;
451 
452 	TeecResult = TEEC_OpenSession(&TeecContext,
453 				&TeecSession,
454 				TeecUuid,
455 				TEEC_LOGIN_PUBLIC,
456 				NULL,
457 				NULL,
458 				&ErrorOrigin);
459 	if (TeecResult != TEEC_SUCCESS)
460 		return TeecResult;
461 
462 	TEEC_SharedMemory SharedMem0 = {0};
463 
464 	SharedMem0.size = length * sizeof(uint32_t);
465 	SharedMem0.flags = 0;
466 
467 	TeecResult = TEEC_AllocateSharedMemory(&TeecContext, &SharedMem0);
468 	if (TeecResult != TEEC_SUCCESS)
469 		goto exit;
470 
471 	TeecOperation.params[0].tmpref.buffer = SharedMem0.buffer;
472 	TeecOperation.params[0].tmpref.size = SharedMem0.size;
473 
474 	if (is_write) {
475 		memcpy(SharedMem0.buffer, buf, SharedMem0.size);
476 		TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
477 							    TEEC_NONE,
478 							    TEEC_NONE,
479 							    TEEC_NONE);
480 
481 	} else {
482 		TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_OUTPUT,
483 							    TEEC_NONE,
484 							    TEEC_NONE,
485 							    TEEC_NONE);
486 	}
487 
488 	TeecResult = TEEC_InvokeCommand(&TeecSession,
489 					cmd,
490 					&TeecOperation,
491 					&ErrorOrigin);
492 	if (TeecResult != TEEC_SUCCESS)
493 		goto exit;
494 
495 	if (!is_write)
496 		memcpy(buf, SharedMem0.buffer, SharedMem0.size);
497 
498 exit:
499 	TEEC_ReleaseSharedMemory(&SharedMem0);
500 	TEEC_CloseSession(&TeecSession);
501 	TEEC_FinalizeContext(&TeecContext);
502 
503 	return TeecResult;
504 }
505 
506 uint32_t trusty_read_attribute_hash(uint32_t *buf, uint32_t length)
507 {
508 	return trusty_base_efuse_or_otp_operation(STORAGE_CMD_READ_ATTRIBUTE_HASH,
509 						  false, buf, length);
510 }
511 
512 uint32_t trusty_write_attribute_hash(uint32_t *buf, uint32_t length)
513 {
514 	return trusty_base_efuse_or_otp_operation(STORAGE_CMD_WRITE_ATTRIBUTE_HASH,
515 						  true, buf, length);
516 }
517 
518 uint32_t trusty_notify_optee_uboot_end(void)
519 {
520 	TEEC_Result res;
521 
522 	res = trusty_base_end_security_data();
523 	res |= trusty_base_end_efuse_or_otp();
524 	return res;
525 }
526 
527 uint32_t trusty_read_vbootkey_hash(uint32_t *buf, uint32_t length)
528 {
529 	return trusty_base_efuse_or_otp_operation(STORAGE_CMD_READ_VBOOTKEY_HASH,
530 						  false, buf, length);
531 }
532 
533 uint32_t trusty_write_vbootkey_hash(uint32_t *buf, uint32_t length)
534 {
535 	return trusty_base_efuse_or_otp_operation(STORAGE_CMD_WRITE_VBOOTKEY_HASH,
536 						  true, buf, length);
537 }
538 
539 uint32_t trusty_read_vbootkey_enable_flag(uint8_t *flag)
540 {
541 	uint32_t bootflag;
542 	TEEC_Result TeecResult;
543 
544 	TeecResult = trusty_base_efuse_or_otp_operation(STORAGE_CMD_READ_ENABLE_FLAG,
545 							false, &bootflag, 1);
546 
547 	if (TeecResult == TEEC_SUCCESS) {
548 #if defined(CONFIG_ROCKCHIP_RK3288)
549 		if (bootflag == 0x00000001)
550 			*flag = 1;
551 #else
552 		if (bootflag == 0x000000FF)
553 			*flag = 1;
554 #endif
555 	}
556 	return TeecResult;
557 }
558 
559 uint32_t trusty_write_ta_encryption_key(uint32_t *buf, uint32_t length)
560 {
561 	return trusty_base_efuse_or_otp_operation(STORAGE_CMD_WRITE_TA_ENCRYPTION_KEY,
562 						  true, buf, length);
563 }
564 
565 uint32_t trusty_check_security_level_flag(uint8_t flag)
566 {
567 	uint32_t levelflag;
568 
569 	levelflag = flag;
570 	return trusty_base_efuse_or_otp_operation(STORAGE_CMD_CHECK_SECURITY_LEVEL_FLAG,
571 						  true, &levelflag, 1);
572 }
573 
574 uint32_t trusty_write_oem_huk(uint32_t *buf, uint32_t length)
575 {
576 	return trusty_base_efuse_or_otp_operation(STORAGE_CMD_WRITE_OEM_HUK,
577 						  true, buf, length);
578 }
579 
580 void trusty_select_security_level(void)
581 {
582 #if (CONFIG_OPTEE_SECURITY_LEVEL > 0)
583 	TEEC_Result TeecResult;
584 
585 	TeecResult = trusty_check_security_level_flag(CONFIG_OPTEE_SECURITY_LEVEL);
586 	if (TeecResult == TEE_ERROR_CANCEL) {
587 		run_command("download", 0);
588 		return;
589 	}
590 
591 	if (TeecResult == TEEC_SUCCESS)
592 		debug("optee select security level success!");
593 	else
594 		panic("optee select security level fail!");
595 
596 	return;
597 #endif
598 }
599 
600 uint32_t trusty_write_oem_ns_otp(uint32_t byte_off, uint8_t *byte_buf, uint32_t byte_len)
601 {
602 	TEEC_Result TeecResult;
603 	TEEC_Context TeecContext;
604 	TEEC_Session TeecSession;
605 	uint32_t ErrorOrigin;
606 
607 	TEEC_UUID tempuuid = { 0x2d26d8a8, 0x5134, 0x4dd8,
608 			{ 0xb3, 0x2f, 0xb3, 0x4b, 0xce, 0xeb, 0xc4, 0x71 } };
609 	TEEC_UUID *TeecUuid = &tempuuid;
610 	TEEC_Operation TeecOperation = {0};
611 
612 	TeecResult = OpteeClientApiLibInitialize();
613 	if (TeecResult != TEEC_SUCCESS)
614 		return TeecResult;
615 
616 	TeecResult = TEEC_InitializeContext(NULL, &TeecContext);
617 	if (TeecResult != TEEC_SUCCESS)
618 		return TeecResult;
619 
620 	TeecResult = TEEC_OpenSession(&TeecContext,
621 				&TeecSession,
622 				TeecUuid,
623 				TEEC_LOGIN_PUBLIC,
624 				NULL,
625 				NULL,
626 				&ErrorOrigin);
627 	if (TeecResult != TEEC_SUCCESS)
628 		return TeecResult;
629 
630 	TeecOperation.params[0].value.a = byte_off;
631 
632 	TEEC_SharedMemory SharedMem = {0};
633 
634 	SharedMem.size = byte_len;
635 	SharedMem.flags = 0;
636 
637 	TeecResult = TEEC_AllocateSharedMemory(&TeecContext, &SharedMem);
638 	if (TeecResult != TEEC_SUCCESS)
639 		goto exit;
640 
641 	TeecOperation.params[1].tmpref.buffer = SharedMem.buffer;
642 	TeecOperation.params[1].tmpref.size = SharedMem.size;
643 
644 	memcpy(SharedMem.buffer, byte_buf, SharedMem.size);
645 	TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
646 						    TEEC_MEMREF_TEMP_INPUT,
647 						    TEEC_NONE,
648 						    TEEC_NONE);
649 
650 	TeecResult = TEEC_InvokeCommand(&TeecSession,
651 					STORAGE_CMD_WRITE_OEM_NS_OTP,
652 					&TeecOperation,
653 					&ErrorOrigin);
654 	if (TeecResult != TEEC_SUCCESS)
655 		goto exit;
656 
657 exit:
658 	TEEC_ReleaseSharedMemory(&SharedMem);
659 	TEEC_CloseSession(&TeecSession);
660 	TEEC_FinalizeContext(&TeecContext);
661 
662 	return TeecResult;
663 }
664 
665 uint32_t trusty_read_oem_ns_otp(uint32_t byte_off, uint8_t *byte_buf, uint32_t byte_len)
666 {
667 	TEEC_Result TeecResult;
668 	TEEC_Context TeecContext;
669 	TEEC_Session TeecSession;
670 	uint32_t ErrorOrigin;
671 
672 	TEEC_UUID tempuuid = { 0x2d26d8a8, 0x5134, 0x4dd8,
673 			{ 0xb3, 0x2f, 0xb3, 0x4b, 0xce, 0xeb, 0xc4, 0x71 } };
674 	TEEC_UUID *TeecUuid = &tempuuid;
675 	TEEC_Operation TeecOperation = {0};
676 
677 	TeecResult = OpteeClientApiLibInitialize();
678 	if (TeecResult != TEEC_SUCCESS)
679 		return TeecResult;
680 
681 	TeecResult = TEEC_InitializeContext(NULL, &TeecContext);
682 	if (TeecResult != TEEC_SUCCESS)
683 		return TeecResult;
684 
685 	TeecResult = TEEC_OpenSession(&TeecContext,
686 				&TeecSession,
687 				TeecUuid,
688 				TEEC_LOGIN_PUBLIC,
689 				NULL,
690 				NULL,
691 				&ErrorOrigin);
692 	if (TeecResult != TEEC_SUCCESS)
693 		return TeecResult;
694 
695 	TeecOperation.params[0].value.a = byte_off;
696 
697 	TEEC_SharedMemory SharedMem = {0};
698 
699 	SharedMem.size = byte_len;
700 	SharedMem.flags = 0;
701 
702 	TeecResult = TEEC_AllocateSharedMemory(&TeecContext, &SharedMem);
703 	if (TeecResult != TEEC_SUCCESS)
704 		goto exit;
705 
706 	TeecOperation.params[1].tmpref.buffer = SharedMem.buffer;
707 	TeecOperation.params[1].tmpref.size = SharedMem.size;
708 
709 	TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
710 						    TEEC_MEMREF_TEMP_OUTPUT,
711 						    TEEC_NONE,
712 						    TEEC_NONE);
713 
714 	TeecResult = TEEC_InvokeCommand(&TeecSession,
715 					STORAGE_CMD_READ_OEM_NS_OTP,
716 					&TeecOperation,
717 					&ErrorOrigin);
718 	if (TeecResult != TEEC_SUCCESS)
719 		goto exit;
720 
721 	memcpy(byte_buf, SharedMem.buffer, SharedMem.size);
722 
723 exit:
724 	TEEC_ReleaseSharedMemory(&SharedMem);
725 	TEEC_CloseSession(&TeecSession);
726 	TEEC_FinalizeContext(&TeecContext);
727 
728 	return TeecResult;
729 }
730 
731 uint32_t trusty_write_oem_hr_otp(enum RK_OEM_HR_OTP_KEYID key_id,
732 				 uint8_t *byte_buf, uint32_t byte_len)
733 {
734 	TEEC_Result TeecResult;
735 	TEEC_Context TeecContext;
736 	TEEC_Session TeecSession;
737 	uint32_t ErrorOrigin;
738 
739 	TEEC_UUID tempuuid = { 0x2d26d8a8, 0x5134, 0x4dd8,
740 			{ 0xb3, 0x2f, 0xb3, 0x4b, 0xce, 0xeb, 0xc4, 0x71 } };
741 	TEEC_UUID *TeecUuid = &tempuuid;
742 	TEEC_Operation TeecOperation = {0};
743 
744 	TeecResult = OpteeClientApiLibInitialize();
745 	if (TeecResult != TEEC_SUCCESS)
746 		return TeecResult;
747 
748 	TeecResult = TEEC_InitializeContext(NULL, &TeecContext);
749 	if (TeecResult != TEEC_SUCCESS)
750 		return TeecResult;
751 
752 	TeecResult = TEEC_OpenSession(&TeecContext,
753 				&TeecSession,
754 				TeecUuid,
755 				TEEC_LOGIN_PUBLIC,
756 				NULL,
757 				NULL,
758 				&ErrorOrigin);
759 	if (TeecResult != TEEC_SUCCESS)
760 		return TeecResult;
761 
762 	TeecOperation.params[0].value.a = key_id;
763 
764 	TEEC_SharedMemory SharedMem = {0};
765 
766 	SharedMem.size = byte_len;
767 	SharedMem.flags = 0;
768 
769 	TeecResult = TEEC_AllocateSharedMemory(&TeecContext, &SharedMem);
770 	if (TeecResult != TEEC_SUCCESS)
771 		goto exit;
772 
773 	TeecOperation.params[1].tmpref.buffer = SharedMem.buffer;
774 	TeecOperation.params[1].tmpref.size = SharedMem.size;
775 
776 	memcpy(SharedMem.buffer, byte_buf, SharedMem.size);
777 	TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
778 						    TEEC_MEMREF_TEMP_INPUT,
779 						    TEEC_NONE,
780 						    TEEC_NONE);
781 
782 	TeecResult = TEEC_InvokeCommand(&TeecSession,
783 					STORAGE_CMD_WRITE_OEM_HR_OTP,
784 					&TeecOperation,
785 					&ErrorOrigin);
786 	if (TeecResult != TEEC_SUCCESS)
787 		goto exit;
788 
789 exit:
790 	TEEC_ReleaseSharedMemory(&SharedMem);
791 	TEEC_CloseSession(&TeecSession);
792 	TEEC_FinalizeContext(&TeecContext);
793 
794 	return TeecResult;
795 }
796 
797 uint32_t trusty_set_oem_hr_otp_read_lock(enum RK_OEM_HR_OTP_KEYID key_id)
798 {
799 	TEEC_Result TeecResult;
800 	TEEC_Context TeecContext;
801 	TEEC_Session TeecSession;
802 	uint32_t ErrorOrigin;
803 
804 	TEEC_UUID tempuuid = { 0x2d26d8a8, 0x5134, 0x4dd8,
805 			{ 0xb3, 0x2f, 0xb3, 0x4b, 0xce, 0xeb, 0xc4, 0x71 } };
806 	TEEC_UUID *TeecUuid = &tempuuid;
807 	TEEC_Operation TeecOperation = {0};
808 
809 	TeecResult = OpteeClientApiLibInitialize();
810 	if (TeecResult != TEEC_SUCCESS)
811 		return TeecResult;
812 
813 	TeecResult = TEEC_InitializeContext(NULL, &TeecContext);
814 	if (TeecResult != TEEC_SUCCESS)
815 		return TeecResult;
816 
817 	TeecResult = TEEC_OpenSession(&TeecContext,
818 				&TeecSession,
819 				TeecUuid,
820 				TEEC_LOGIN_PUBLIC,
821 				NULL,
822 				NULL,
823 				&ErrorOrigin);
824 	if (TeecResult != TEEC_SUCCESS)
825 		return TeecResult;
826 
827 	TeecOperation.params[0].value.a = key_id;
828 
829 	TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
830 						    TEEC_NONE,
831 						    TEEC_NONE,
832 						    TEEC_NONE);
833 
834 	TeecResult = TEEC_InvokeCommand(&TeecSession,
835 					STORAGE_CMD_SET_OEM_HR_OTP_READ_LOCK,
836 					&TeecOperation,
837 					&ErrorOrigin);
838 	if (TeecResult != TEEC_SUCCESS)
839 		goto exit;
840 
841 exit:
842 	TEEC_CloseSession(&TeecSession);
843 	TEEC_FinalizeContext(&TeecContext);
844 
845 	return TeecResult;
846 }
847 
848 uint32_t trusty_attest_dh(uint8_t *dh, uint32_t *dh_size)
849 {
850 	TEEC_Result TeecResult;
851 	TEEC_Context TeecContext;
852 	TEEC_Session TeecSession;
853 	uint32_t ErrorOrigin;
854 	TEEC_UUID tempuuid = { 0x258be795, 0xf9ca, 0x40e6,
855 				{ 0xa8, 0x69, 0x9c, 0xe6,
856 				  0x88, 0x6c, 0x5d, 0x5d
857 				}
858 			     };
859 	TEEC_UUID *TeecUuid = &tempuuid;
860 	TEEC_Operation TeecOperation = {0};
861 	struct blk_desc *dev_desc;
862 	dev_desc = rockchip_get_bootdev();
863 	if (!dev_desc) {
864 		printf("%s: dev_desc is NULL!\n", __func__);
865 		return -TEEC_ERROR_GENERIC;
866 	}
867 
868 	TeecResult = OpteeClientApiLibInitialize();
869 	if (TeecResult != TEEC_SUCCESS)
870 		return TeecResult;
871 
872 	TeecResult = TEEC_InitializeContext(NULL, &TeecContext);
873 	if (TeecResult != TEEC_SUCCESS)
874 		return TeecResult;
875 
876 	TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
877 						TEEC_NONE,
878 						TEEC_NONE,
879 						TEEC_NONE);
880 	/*0 nand or emmc "security" partition , 1 rpmb*/
881 	if (dev_desc->if_type == IF_TYPE_MMC && dev_desc->devnum == 0)
882 		TeecOperation.params[0].value.a = 1;
883 	else
884 		TeecOperation.params[0].value.a = 0;
885 
886 #ifdef CONFIG_OPTEE_ALWAYS_USE_SECURITY_PARTITION
887 	TeecOperation.params[0].value.a = 0;
888 #endif
889 
890 	TeecResult = TEEC_OpenSession(&TeecContext,
891 				      &TeecSession,
892 				      TeecUuid,
893 				      TEEC_LOGIN_PUBLIC,
894 				      NULL,
895 					&TeecOperation,
896 				      &ErrorOrigin);
897 	if (TeecResult != TEEC_SUCCESS)
898 		return TeecResult;
899 
900 	TEEC_SharedMemory SharedMem0 = {0};
901 
902 	SharedMem0.size = *dh_size;
903 	SharedMem0.flags = 0;
904 
905 	TeecResult = TEEC_AllocateSharedMemory(&TeecContext, &SharedMem0);
906 	if (TeecResult != TEEC_SUCCESS)
907 		goto exit;
908 
909 	TeecOperation.params[0].tmpref.buffer = SharedMem0.buffer;
910 	TeecOperation.params[0].tmpref.size = SharedMem0.size;
911 
912 	TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INOUT,
913 						    TEEC_NONE,
914 						    TEEC_NONE,
915 						    TEEC_NONE);
916 
917 	TeecResult = TEEC_InvokeCommand(&TeecSession,
918 					143,
919 					&TeecOperation,
920 					&ErrorOrigin);
921 	if (TeecResult != TEEC_SUCCESS)
922 		goto exit;
923 
924 	*dh_size = TeecOperation.params[0].tmpref.size;
925 	memcpy(dh, SharedMem0.buffer, SharedMem0.size);
926 exit:
927 	TEEC_ReleaseSharedMemory(&SharedMem0);
928 	TEEC_CloseSession(&TeecSession);
929 	TEEC_FinalizeContext(&TeecContext);
930 
931 	return TeecResult;
932 }
933 
934 uint32_t trusty_attest_uuid(uint8_t *uuid, uint32_t *uuid_size)
935 {
936 	TEEC_Result TeecResult;
937 	TEEC_Context TeecContext;
938 	TEEC_Session TeecSession;
939 	uint32_t ErrorOrigin;
940 	TEEC_UUID tempuuid = { 0x258be795, 0xf9ca, 0x40e6,
941 				{ 0xa8, 0x69, 0x9c, 0xe6,
942 				  0x88, 0x6c, 0x5d, 0x5d
943 				}
944 			     };
945 	TEEC_UUID *TeecUuid = &tempuuid;
946 	TEEC_Operation TeecOperation = {0};
947 	struct blk_desc *dev_desc;
948 	dev_desc = rockchip_get_bootdev();
949 	if (!dev_desc) {
950 		printf("%s: dev_desc is NULL!\n", __func__);
951 		return -TEEC_ERROR_GENERIC;
952 	}
953 
954 	TeecResult = OpteeClientApiLibInitialize();
955 	if (TeecResult != TEEC_SUCCESS)
956 		return TeecResult;
957 
958 	TeecResult = TEEC_InitializeContext(NULL, &TeecContext);
959 	if (TeecResult != TEEC_SUCCESS)
960 		return TeecResult;
961 
962 	TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
963 						TEEC_NONE,
964 						TEEC_NONE,
965 						TEEC_NONE);
966 	/*0 nand or emmc "security" partition , 1 rpmb*/
967 	if (dev_desc->if_type == IF_TYPE_MMC && dev_desc->devnum == 0)
968 		TeecOperation.params[0].value.a = 1;
969 	else
970 		TeecOperation.params[0].value.a = 0;
971 
972 #ifdef CONFIG_OPTEE_ALWAYS_USE_SECURITY_PARTITION
973 	TeecOperation.params[0].value.a = 0;
974 #endif
975 
976 	TeecResult = TEEC_OpenSession(&TeecContext,
977 				      &TeecSession,
978 				      TeecUuid,
979 				      TEEC_LOGIN_PUBLIC,
980 				      NULL,
981 					&TeecOperation,
982 				      &ErrorOrigin);
983 	if (TeecResult != TEEC_SUCCESS)
984 		return TeecResult;
985 
986 	TEEC_SharedMemory SharedMem0 = {0};
987 
988 	SharedMem0.size = *uuid_size;
989 	SharedMem0.flags = 0;
990 
991 	TeecResult = TEEC_AllocateSharedMemory(&TeecContext, &SharedMem0);
992 	if (TeecResult != TEEC_SUCCESS)
993 		goto exit;
994 
995 	TeecOperation.params[0].tmpref.buffer = SharedMem0.buffer;
996 	TeecOperation.params[0].tmpref.size = SharedMem0.size;
997 
998 	TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INOUT,
999 						    TEEC_NONE,
1000 						    TEEC_NONE,
1001 						    TEEC_NONE);
1002 
1003 	TeecResult = TEEC_InvokeCommand(&TeecSession,
1004 					144,
1005 					&TeecOperation,
1006 					&ErrorOrigin);
1007 	if (TeecResult != TEEC_SUCCESS)
1008 		goto exit;
1009 
1010 	*uuid_size = TeecOperation.params[0].tmpref.size;
1011 	memcpy(uuid, SharedMem0.buffer, SharedMem0.size);
1012 exit:
1013 	TEEC_ReleaseSharedMemory(&SharedMem0);
1014 	TEEC_CloseSession(&TeecSession);
1015 	TEEC_FinalizeContext(&TeecContext);
1016 
1017 	return TeecResult;
1018 }
1019 
1020 uint32_t trusty_attest_get_ca(uint8_t *operation_start,
1021 			      uint32_t *operation_size,
1022 			      uint8_t *out,
1023 			      uint32_t *out_len)
1024 {
1025 	TEEC_Result TeecResult;
1026 	TEEC_Context TeecContext;
1027 	TEEC_Session TeecSession;
1028 	uint32_t ErrorOrigin;
1029 
1030 	TEEC_UUID tempuuid = { 0x258be795, 0xf9ca, 0x40e6,
1031 				{ 0xa8, 0x69, 0x9c, 0xe6,
1032 				  0x88, 0x6c, 0x5d, 0x5d
1033 				}
1034 			     };
1035 
1036 	TEEC_UUID *TeecUuid = &tempuuid;
1037 	TEEC_Operation TeecOperation = {0};
1038 	struct blk_desc *dev_desc;
1039 	dev_desc = rockchip_get_bootdev();
1040 	if (!dev_desc) {
1041 		printf("%s: dev_desc is NULL!\n", __func__);
1042 		return -TEEC_ERROR_GENERIC;
1043 	}
1044 
1045 	TeecResult = OpteeClientApiLibInitialize();
1046 	if (TeecResult != TEEC_SUCCESS)
1047 		return TeecResult;
1048 
1049 	TeecResult = TEEC_InitializeContext(NULL, &TeecContext);
1050 	if (TeecResult != TEEC_SUCCESS)
1051 		return TeecResult;
1052 
1053 	TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
1054 						TEEC_NONE,
1055 						TEEC_NONE,
1056 						TEEC_NONE);
1057 	/*0 nand or emmc "security" partition , 1 rpmb*/
1058 	if (dev_desc->if_type == IF_TYPE_MMC && dev_desc->devnum == 0)
1059 		TeecOperation.params[0].value.a = 1;
1060 	else
1061 		TeecOperation.params[0].value.a = 0;
1062 
1063 #ifdef CONFIG_OPTEE_ALWAYS_USE_SECURITY_PARTITION
1064 	TeecOperation.params[0].value.a = 0;
1065 #endif
1066 
1067 	TeecResult = TEEC_OpenSession(&TeecContext,
1068 				      &TeecSession,
1069 				      TeecUuid,
1070 				      TEEC_LOGIN_PUBLIC,
1071 				      NULL,
1072 					&TeecOperation,
1073 				      &ErrorOrigin);
1074 	if (TeecResult != TEEC_SUCCESS)
1075 		return TeecResult;
1076 
1077 	TEEC_SharedMemory SharedMem0 = {0};
1078 
1079 	SharedMem0.size = *operation_size;
1080 	SharedMem0.flags = 0;
1081 
1082 	TeecResult = TEEC_AllocateSharedMemory(&TeecContext, &SharedMem0);
1083 	if (TeecResult != TEEC_SUCCESS)
1084 		goto exit;
1085 
1086 	memcpy(SharedMem0.buffer, operation_start, SharedMem0.size);
1087 
1088 	TeecOperation.params[0].tmpref.buffer = SharedMem0.buffer;
1089 	TeecOperation.params[0].tmpref.size = SharedMem0.size;
1090 
1091 	TEEC_SharedMemory SharedMem1 = {0};
1092 
1093 	SharedMem1.size = *out_len;
1094 	SharedMem1.flags = 0;
1095 
1096 	TeecResult = TEEC_AllocateSharedMemory(&TeecContext, &SharedMem1);
1097 	if (TeecResult != TEEC_SUCCESS)
1098 		goto exit;
1099 
1100 	TeecOperation.params[1].tmpref.buffer = SharedMem1.buffer;
1101 	TeecOperation.params[1].tmpref.size = SharedMem1.size;
1102 
1103 	TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INOUT,
1104 						    TEEC_MEMREF_TEMP_INOUT,
1105 						    TEEC_NONE,
1106 						    TEEC_NONE);
1107 
1108 	TeecResult = TEEC_InvokeCommand(&TeecSession,
1109 					145,
1110 					&TeecOperation,
1111 					&ErrorOrigin);
1112 	if (TeecResult != TEEC_SUCCESS)
1113 		goto exit;
1114 
1115 	*out_len = TeecOperation.params[1].tmpref.size;
1116 	memcpy(out, SharedMem1.buffer, SharedMem1.size);
1117 exit:
1118 	TEEC_ReleaseSharedMemory(&SharedMem0);
1119 	TEEC_ReleaseSharedMemory(&SharedMem1);
1120 	TEEC_CloseSession(&TeecSession);
1121 	TEEC_FinalizeContext(&TeecContext);
1122 
1123 	return TeecResult;
1124 }
1125 
1126 uint32_t trusty_attest_set_ca(uint8_t *ca_response, uint32_t *ca_response_size)
1127 {
1128 	TEEC_Result TeecResult;
1129 	TEEC_Context TeecContext;
1130 	TEEC_Session TeecSession;
1131 	uint32_t ErrorOrigin;
1132 	TEEC_UUID tempuuid = { 0x258be795, 0xf9ca, 0x40e6,
1133 				{ 0xa8, 0x69, 0x9c, 0xe6,
1134 				  0x88, 0x6c, 0x5d, 0x5d
1135 				}
1136 			     };
1137 	TEEC_UUID *TeecUuid = &tempuuid;
1138 	TEEC_Operation TeecOperation = {0};
1139 	struct blk_desc *dev_desc;
1140 	dev_desc = rockchip_get_bootdev();
1141 	if (!dev_desc) {
1142 		printf("%s: dev_desc is NULL!\n", __func__);
1143 		return -TEEC_ERROR_GENERIC;
1144 	}
1145 	TeecResult = OpteeClientApiLibInitialize();
1146 	if (TeecResult != TEEC_SUCCESS)
1147 		return TeecResult;
1148 
1149 	TeecResult = TEEC_InitializeContext(NULL, &TeecContext);
1150 	if (TeecResult != TEEC_SUCCESS)
1151 		return TeecResult;
1152 
1153 	TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
1154 						TEEC_NONE,
1155 						TEEC_NONE,
1156 						TEEC_NONE);
1157 	/*0 nand or emmc "security" partition , 1 rpmb*/
1158 	if (dev_desc->if_type == IF_TYPE_MMC && dev_desc->devnum == 0)
1159 		TeecOperation.params[0].value.a = 1;
1160 	else
1161 		TeecOperation.params[0].value.a = 0;
1162 
1163 #ifdef CONFIG_OPTEE_ALWAYS_USE_SECURITY_PARTITION
1164 	TeecOperation.params[0].value.a = 0;
1165 #endif
1166 
1167 	TeecResult = TEEC_OpenSession(&TeecContext,
1168 					&TeecSession,
1169 					TeecUuid,
1170 					TEEC_LOGIN_PUBLIC,
1171 					NULL,
1172 					&TeecOperation,
1173 					&ErrorOrigin);
1174 	if (TeecResult != TEEC_SUCCESS)
1175 		return TeecResult;
1176 
1177 	TEEC_SharedMemory SharedMem0 = {0};
1178 
1179 	SharedMem0.size = *ca_response_size;
1180 	SharedMem0.flags = 0;
1181 
1182 	TeecResult = TEEC_AllocateSharedMemory(&TeecContext, &SharedMem0);
1183 	if (TeecResult != TEEC_SUCCESS)
1184 		goto exit;
1185 
1186 	memcpy(SharedMem0.buffer, ca_response, SharedMem0.size);
1187 
1188 	TeecOperation.params[0].tmpref.buffer = SharedMem0.buffer;
1189 	TeecOperation.params[0].tmpref.size = SharedMem0.size;
1190 
1191 	TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INOUT,
1192 						    TEEC_NONE,
1193 						    TEEC_NONE,
1194 						    TEEC_NONE);
1195 
1196 	TeecResult = TEEC_InvokeCommand(&TeecSession,
1197 					146,
1198 					&TeecOperation,
1199 					&ErrorOrigin);
1200 	if (TeecResult != TEEC_SUCCESS)
1201 		goto exit;
1202 exit:
1203 	TEEC_ReleaseSharedMemory(&SharedMem0);
1204 	TEEC_CloseSession(&TeecSession);
1205 	TEEC_FinalizeContext(&TeecContext);
1206 
1207 	return TeecResult;
1208 }
1209