xref: /rk3399_rockchip-uboot/lib/optee_clientApi/OpteeClientInterface.c (revision f07e1686b88062b32d38b5b1b7bfd4685ae29a67)
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 	*flag = 0;
545 
546 	TeecResult = trusty_base_efuse_or_otp_operation(STORAGE_CMD_READ_ENABLE_FLAG,
547 							false, &bootflag, 1);
548 
549 	if (TeecResult == TEEC_SUCCESS) {
550 #if defined(CONFIG_ROCKCHIP_RK3288)
551 		if (bootflag == 0x00000001)
552 			*flag = 1;
553 #else
554 		if (bootflag == 0x000000FF)
555 			*flag = 1;
556 #endif
557 	}
558 	return TeecResult;
559 }
560 
561 uint32_t trusty_write_ta_encryption_key(uint32_t *buf, uint32_t length)
562 {
563 	return trusty_base_efuse_or_otp_operation(STORAGE_CMD_WRITE_TA_ENCRYPTION_KEY,
564 						  true, buf, length);
565 }
566 
567 uint32_t trusty_check_security_level_flag(uint8_t flag)
568 {
569 	uint32_t levelflag;
570 
571 	levelflag = flag;
572 	return trusty_base_efuse_or_otp_operation(STORAGE_CMD_CHECK_SECURITY_LEVEL_FLAG,
573 						  true, &levelflag, 1);
574 }
575 
576 uint32_t trusty_write_oem_huk(uint32_t *buf, uint32_t length)
577 {
578 	return trusty_base_efuse_or_otp_operation(STORAGE_CMD_WRITE_OEM_HUK,
579 						  true, buf, length);
580 }
581 
582 void trusty_select_security_level(void)
583 {
584 #if (CONFIG_OPTEE_SECURITY_LEVEL > 0)
585 	TEEC_Result TeecResult;
586 
587 	TeecResult = trusty_check_security_level_flag(CONFIG_OPTEE_SECURITY_LEVEL);
588 	if (TeecResult == TEE_ERROR_CANCEL) {
589 		run_command("download", 0);
590 		return;
591 	}
592 
593 	if (TeecResult == TEEC_SUCCESS)
594 		debug("optee select security level success!");
595 	else
596 		panic("optee select security level fail!");
597 
598 	return;
599 #endif
600 }
601 
602 uint32_t trusty_write_oem_ns_otp(uint32_t byte_off, uint8_t *byte_buf, uint32_t byte_len)
603 {
604 	TEEC_Result TeecResult;
605 	TEEC_Context TeecContext;
606 	TEEC_Session TeecSession;
607 	uint32_t ErrorOrigin;
608 
609 	TEEC_UUID tempuuid = { 0x2d26d8a8, 0x5134, 0x4dd8,
610 			{ 0xb3, 0x2f, 0xb3, 0x4b, 0xce, 0xeb, 0xc4, 0x71 } };
611 	TEEC_UUID *TeecUuid = &tempuuid;
612 	TEEC_Operation TeecOperation = {0};
613 
614 	TeecResult = OpteeClientApiLibInitialize();
615 	if (TeecResult != TEEC_SUCCESS)
616 		return TeecResult;
617 
618 	TeecResult = TEEC_InitializeContext(NULL, &TeecContext);
619 	if (TeecResult != TEEC_SUCCESS)
620 		return TeecResult;
621 
622 	TeecResult = TEEC_OpenSession(&TeecContext,
623 				&TeecSession,
624 				TeecUuid,
625 				TEEC_LOGIN_PUBLIC,
626 				NULL,
627 				NULL,
628 				&ErrorOrigin);
629 	if (TeecResult != TEEC_SUCCESS)
630 		return TeecResult;
631 
632 	TeecOperation.params[0].value.a = byte_off;
633 
634 	TEEC_SharedMemory SharedMem = {0};
635 
636 	SharedMem.size = byte_len;
637 	SharedMem.flags = 0;
638 
639 	TeecResult = TEEC_AllocateSharedMemory(&TeecContext, &SharedMem);
640 	if (TeecResult != TEEC_SUCCESS)
641 		goto exit;
642 
643 	TeecOperation.params[1].tmpref.buffer = SharedMem.buffer;
644 	TeecOperation.params[1].tmpref.size = SharedMem.size;
645 
646 	memcpy(SharedMem.buffer, byte_buf, SharedMem.size);
647 	TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
648 						    TEEC_MEMREF_TEMP_INPUT,
649 						    TEEC_NONE,
650 						    TEEC_NONE);
651 
652 	TeecResult = TEEC_InvokeCommand(&TeecSession,
653 					STORAGE_CMD_WRITE_OEM_NS_OTP,
654 					&TeecOperation,
655 					&ErrorOrigin);
656 	if (TeecResult != TEEC_SUCCESS)
657 		goto exit;
658 
659 exit:
660 	TEEC_ReleaseSharedMemory(&SharedMem);
661 	TEEC_CloseSession(&TeecSession);
662 	TEEC_FinalizeContext(&TeecContext);
663 
664 	return TeecResult;
665 }
666 
667 uint32_t trusty_read_oem_ns_otp(uint32_t byte_off, uint8_t *byte_buf, uint32_t byte_len)
668 {
669 	TEEC_Result TeecResult;
670 	TEEC_Context TeecContext;
671 	TEEC_Session TeecSession;
672 	uint32_t ErrorOrigin;
673 
674 	TEEC_UUID tempuuid = { 0x2d26d8a8, 0x5134, 0x4dd8,
675 			{ 0xb3, 0x2f, 0xb3, 0x4b, 0xce, 0xeb, 0xc4, 0x71 } };
676 	TEEC_UUID *TeecUuid = &tempuuid;
677 	TEEC_Operation TeecOperation = {0};
678 
679 	TeecResult = OpteeClientApiLibInitialize();
680 	if (TeecResult != TEEC_SUCCESS)
681 		return TeecResult;
682 
683 	TeecResult = TEEC_InitializeContext(NULL, &TeecContext);
684 	if (TeecResult != TEEC_SUCCESS)
685 		return TeecResult;
686 
687 	TeecResult = TEEC_OpenSession(&TeecContext,
688 				&TeecSession,
689 				TeecUuid,
690 				TEEC_LOGIN_PUBLIC,
691 				NULL,
692 				NULL,
693 				&ErrorOrigin);
694 	if (TeecResult != TEEC_SUCCESS)
695 		return TeecResult;
696 
697 	TeecOperation.params[0].value.a = byte_off;
698 
699 	TEEC_SharedMemory SharedMem = {0};
700 
701 	SharedMem.size = byte_len;
702 	SharedMem.flags = 0;
703 
704 	TeecResult = TEEC_AllocateSharedMemory(&TeecContext, &SharedMem);
705 	if (TeecResult != TEEC_SUCCESS)
706 		goto exit;
707 
708 	TeecOperation.params[1].tmpref.buffer = SharedMem.buffer;
709 	TeecOperation.params[1].tmpref.size = SharedMem.size;
710 
711 	TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
712 						    TEEC_MEMREF_TEMP_OUTPUT,
713 						    TEEC_NONE,
714 						    TEEC_NONE);
715 
716 	TeecResult = TEEC_InvokeCommand(&TeecSession,
717 					STORAGE_CMD_READ_OEM_NS_OTP,
718 					&TeecOperation,
719 					&ErrorOrigin);
720 	if (TeecResult != TEEC_SUCCESS)
721 		goto exit;
722 
723 	memcpy(byte_buf, SharedMem.buffer, SharedMem.size);
724 
725 exit:
726 	TEEC_ReleaseSharedMemory(&SharedMem);
727 	TEEC_CloseSession(&TeecSession);
728 	TEEC_FinalizeContext(&TeecContext);
729 
730 	return TeecResult;
731 }
732 
733 uint32_t trusty_write_oem_hr_otp(enum RK_OEM_HR_OTP_KEYID key_id,
734 				 uint8_t *byte_buf, uint32_t byte_len)
735 {
736 	TEEC_Result TeecResult;
737 	TEEC_Context TeecContext;
738 	TEEC_Session TeecSession;
739 	uint32_t ErrorOrigin;
740 
741 	TEEC_UUID tempuuid = { 0x2d26d8a8, 0x5134, 0x4dd8,
742 			{ 0xb3, 0x2f, 0xb3, 0x4b, 0xce, 0xeb, 0xc4, 0x71 } };
743 	TEEC_UUID *TeecUuid = &tempuuid;
744 	TEEC_Operation TeecOperation = {0};
745 
746 	TeecResult = OpteeClientApiLibInitialize();
747 	if (TeecResult != TEEC_SUCCESS)
748 		return TeecResult;
749 
750 	TeecResult = TEEC_InitializeContext(NULL, &TeecContext);
751 	if (TeecResult != TEEC_SUCCESS)
752 		return TeecResult;
753 
754 	TeecResult = TEEC_OpenSession(&TeecContext,
755 				&TeecSession,
756 				TeecUuid,
757 				TEEC_LOGIN_PUBLIC,
758 				NULL,
759 				NULL,
760 				&ErrorOrigin);
761 	if (TeecResult != TEEC_SUCCESS)
762 		return TeecResult;
763 
764 	TeecOperation.params[0].value.a = key_id;
765 
766 	TEEC_SharedMemory SharedMem = {0};
767 
768 	SharedMem.size = byte_len;
769 	SharedMem.flags = 0;
770 
771 	TeecResult = TEEC_AllocateSharedMemory(&TeecContext, &SharedMem);
772 	if (TeecResult != TEEC_SUCCESS)
773 		goto exit;
774 
775 	TeecOperation.params[1].tmpref.buffer = SharedMem.buffer;
776 	TeecOperation.params[1].tmpref.size = SharedMem.size;
777 
778 	memcpy(SharedMem.buffer, byte_buf, SharedMem.size);
779 	TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
780 						    TEEC_MEMREF_TEMP_INPUT,
781 						    TEEC_NONE,
782 						    TEEC_NONE);
783 
784 	TeecResult = TEEC_InvokeCommand(&TeecSession,
785 					STORAGE_CMD_WRITE_OEM_HR_OTP,
786 					&TeecOperation,
787 					&ErrorOrigin);
788 	if (TeecResult != TEEC_SUCCESS)
789 		goto exit;
790 
791 exit:
792 	TEEC_ReleaseSharedMemory(&SharedMem);
793 	TEEC_CloseSession(&TeecSession);
794 	TEEC_FinalizeContext(&TeecContext);
795 
796 	return TeecResult;
797 }
798 
799 uint32_t trusty_set_oem_hr_otp_read_lock(enum RK_OEM_HR_OTP_KEYID key_id)
800 {
801 	TEEC_Result TeecResult;
802 	TEEC_Context TeecContext;
803 	TEEC_Session TeecSession;
804 	uint32_t ErrorOrigin;
805 
806 	TEEC_UUID tempuuid = { 0x2d26d8a8, 0x5134, 0x4dd8,
807 			{ 0xb3, 0x2f, 0xb3, 0x4b, 0xce, 0xeb, 0xc4, 0x71 } };
808 	TEEC_UUID *TeecUuid = &tempuuid;
809 	TEEC_Operation TeecOperation = {0};
810 
811 	TeecResult = OpteeClientApiLibInitialize();
812 	if (TeecResult != TEEC_SUCCESS)
813 		return TeecResult;
814 
815 	TeecResult = TEEC_InitializeContext(NULL, &TeecContext);
816 	if (TeecResult != TEEC_SUCCESS)
817 		return TeecResult;
818 
819 	TeecResult = TEEC_OpenSession(&TeecContext,
820 				&TeecSession,
821 				TeecUuid,
822 				TEEC_LOGIN_PUBLIC,
823 				NULL,
824 				NULL,
825 				&ErrorOrigin);
826 	if (TeecResult != TEEC_SUCCESS)
827 		return TeecResult;
828 
829 	TeecOperation.params[0].value.a = key_id;
830 
831 	TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
832 						    TEEC_NONE,
833 						    TEEC_NONE,
834 						    TEEC_NONE);
835 
836 	TeecResult = TEEC_InvokeCommand(&TeecSession,
837 					STORAGE_CMD_SET_OEM_HR_OTP_READ_LOCK,
838 					&TeecOperation,
839 					&ErrorOrigin);
840 	if (TeecResult != TEEC_SUCCESS)
841 		goto exit;
842 
843 exit:
844 	TEEC_CloseSession(&TeecSession);
845 	TEEC_FinalizeContext(&TeecContext);
846 
847 	return TeecResult;
848 }
849 
850 uint32_t trusty_attest_dh(uint8_t *dh, uint32_t *dh_size)
851 {
852 	TEEC_Result TeecResult;
853 	TEEC_Context TeecContext;
854 	TEEC_Session TeecSession;
855 	uint32_t ErrorOrigin;
856 	TEEC_UUID tempuuid = { 0x258be795, 0xf9ca, 0x40e6,
857 				{ 0xa8, 0x69, 0x9c, 0xe6,
858 				  0x88, 0x6c, 0x5d, 0x5d
859 				}
860 			     };
861 	TEEC_UUID *TeecUuid = &tempuuid;
862 	TEEC_Operation TeecOperation = {0};
863 	struct blk_desc *dev_desc;
864 	dev_desc = rockchip_get_bootdev();
865 	if (!dev_desc) {
866 		printf("%s: dev_desc is NULL!\n", __func__);
867 		return -TEEC_ERROR_GENERIC;
868 	}
869 
870 	TeecResult = OpteeClientApiLibInitialize();
871 	if (TeecResult != TEEC_SUCCESS)
872 		return TeecResult;
873 
874 	TeecResult = TEEC_InitializeContext(NULL, &TeecContext);
875 	if (TeecResult != TEEC_SUCCESS)
876 		return TeecResult;
877 
878 	TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
879 						TEEC_NONE,
880 						TEEC_NONE,
881 						TEEC_NONE);
882 	/*0 nand or emmc "security" partition , 1 rpmb*/
883 	if (dev_desc->if_type == IF_TYPE_MMC && dev_desc->devnum == 0)
884 		TeecOperation.params[0].value.a = 1;
885 	else
886 		TeecOperation.params[0].value.a = 0;
887 
888 #ifdef CONFIG_OPTEE_ALWAYS_USE_SECURITY_PARTITION
889 	TeecOperation.params[0].value.a = 0;
890 #endif
891 
892 	TeecResult = TEEC_OpenSession(&TeecContext,
893 				      &TeecSession,
894 				      TeecUuid,
895 				      TEEC_LOGIN_PUBLIC,
896 				      NULL,
897 					&TeecOperation,
898 				      &ErrorOrigin);
899 	if (TeecResult != TEEC_SUCCESS)
900 		return TeecResult;
901 
902 	TEEC_SharedMemory SharedMem0 = {0};
903 
904 	SharedMem0.size = *dh_size;
905 	SharedMem0.flags = 0;
906 
907 	TeecResult = TEEC_AllocateSharedMemory(&TeecContext, &SharedMem0);
908 	if (TeecResult != TEEC_SUCCESS)
909 		goto exit;
910 
911 	TeecOperation.params[0].tmpref.buffer = SharedMem0.buffer;
912 	TeecOperation.params[0].tmpref.size = SharedMem0.size;
913 
914 	TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INOUT,
915 						    TEEC_NONE,
916 						    TEEC_NONE,
917 						    TEEC_NONE);
918 
919 	TeecResult = TEEC_InvokeCommand(&TeecSession,
920 					143,
921 					&TeecOperation,
922 					&ErrorOrigin);
923 	if (TeecResult != TEEC_SUCCESS)
924 		goto exit;
925 
926 	*dh_size = TeecOperation.params[0].tmpref.size;
927 	memcpy(dh, SharedMem0.buffer, SharedMem0.size);
928 exit:
929 	TEEC_ReleaseSharedMemory(&SharedMem0);
930 	TEEC_CloseSession(&TeecSession);
931 	TEEC_FinalizeContext(&TeecContext);
932 
933 	return TeecResult;
934 }
935 
936 uint32_t trusty_attest_uuid(uint8_t *uuid, uint32_t *uuid_size)
937 {
938 	TEEC_Result TeecResult;
939 	TEEC_Context TeecContext;
940 	TEEC_Session TeecSession;
941 	uint32_t ErrorOrigin;
942 	TEEC_UUID tempuuid = { 0x258be795, 0xf9ca, 0x40e6,
943 				{ 0xa8, 0x69, 0x9c, 0xe6,
944 				  0x88, 0x6c, 0x5d, 0x5d
945 				}
946 			     };
947 	TEEC_UUID *TeecUuid = &tempuuid;
948 	TEEC_Operation TeecOperation = {0};
949 	struct blk_desc *dev_desc;
950 	dev_desc = rockchip_get_bootdev();
951 	if (!dev_desc) {
952 		printf("%s: dev_desc is NULL!\n", __func__);
953 		return -TEEC_ERROR_GENERIC;
954 	}
955 
956 	TeecResult = OpteeClientApiLibInitialize();
957 	if (TeecResult != TEEC_SUCCESS)
958 		return TeecResult;
959 
960 	TeecResult = TEEC_InitializeContext(NULL, &TeecContext);
961 	if (TeecResult != TEEC_SUCCESS)
962 		return TeecResult;
963 
964 	TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
965 						TEEC_NONE,
966 						TEEC_NONE,
967 						TEEC_NONE);
968 	/*0 nand or emmc "security" partition , 1 rpmb*/
969 	if (dev_desc->if_type == IF_TYPE_MMC && dev_desc->devnum == 0)
970 		TeecOperation.params[0].value.a = 1;
971 	else
972 		TeecOperation.params[0].value.a = 0;
973 
974 #ifdef CONFIG_OPTEE_ALWAYS_USE_SECURITY_PARTITION
975 	TeecOperation.params[0].value.a = 0;
976 #endif
977 
978 	TeecResult = TEEC_OpenSession(&TeecContext,
979 				      &TeecSession,
980 				      TeecUuid,
981 				      TEEC_LOGIN_PUBLIC,
982 				      NULL,
983 					&TeecOperation,
984 				      &ErrorOrigin);
985 	if (TeecResult != TEEC_SUCCESS)
986 		return TeecResult;
987 
988 	TEEC_SharedMemory SharedMem0 = {0};
989 
990 	SharedMem0.size = *uuid_size;
991 	SharedMem0.flags = 0;
992 
993 	TeecResult = TEEC_AllocateSharedMemory(&TeecContext, &SharedMem0);
994 	if (TeecResult != TEEC_SUCCESS)
995 		goto exit;
996 
997 	TeecOperation.params[0].tmpref.buffer = SharedMem0.buffer;
998 	TeecOperation.params[0].tmpref.size = SharedMem0.size;
999 
1000 	TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INOUT,
1001 						    TEEC_NONE,
1002 						    TEEC_NONE,
1003 						    TEEC_NONE);
1004 
1005 	TeecResult = TEEC_InvokeCommand(&TeecSession,
1006 					144,
1007 					&TeecOperation,
1008 					&ErrorOrigin);
1009 	if (TeecResult != TEEC_SUCCESS)
1010 		goto exit;
1011 
1012 	*uuid_size = TeecOperation.params[0].tmpref.size;
1013 	memcpy(uuid, SharedMem0.buffer, SharedMem0.size);
1014 exit:
1015 	TEEC_ReleaseSharedMemory(&SharedMem0);
1016 	TEEC_CloseSession(&TeecSession);
1017 	TEEC_FinalizeContext(&TeecContext);
1018 
1019 	return TeecResult;
1020 }
1021 
1022 uint32_t trusty_attest_get_ca(uint8_t *operation_start,
1023 			      uint32_t *operation_size,
1024 			      uint8_t *out,
1025 			      uint32_t *out_len)
1026 {
1027 	TEEC_Result TeecResult;
1028 	TEEC_Context TeecContext;
1029 	TEEC_Session TeecSession;
1030 	uint32_t ErrorOrigin;
1031 
1032 	TEEC_UUID tempuuid = { 0x258be795, 0xf9ca, 0x40e6,
1033 				{ 0xa8, 0x69, 0x9c, 0xe6,
1034 				  0x88, 0x6c, 0x5d, 0x5d
1035 				}
1036 			     };
1037 
1038 	TEEC_UUID *TeecUuid = &tempuuid;
1039 	TEEC_Operation TeecOperation = {0};
1040 	struct blk_desc *dev_desc;
1041 	dev_desc = rockchip_get_bootdev();
1042 	if (!dev_desc) {
1043 		printf("%s: dev_desc is NULL!\n", __func__);
1044 		return -TEEC_ERROR_GENERIC;
1045 	}
1046 
1047 	TeecResult = OpteeClientApiLibInitialize();
1048 	if (TeecResult != TEEC_SUCCESS)
1049 		return TeecResult;
1050 
1051 	TeecResult = TEEC_InitializeContext(NULL, &TeecContext);
1052 	if (TeecResult != TEEC_SUCCESS)
1053 		return TeecResult;
1054 
1055 	TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
1056 						TEEC_NONE,
1057 						TEEC_NONE,
1058 						TEEC_NONE);
1059 	/*0 nand or emmc "security" partition , 1 rpmb*/
1060 	if (dev_desc->if_type == IF_TYPE_MMC && dev_desc->devnum == 0)
1061 		TeecOperation.params[0].value.a = 1;
1062 	else
1063 		TeecOperation.params[0].value.a = 0;
1064 
1065 #ifdef CONFIG_OPTEE_ALWAYS_USE_SECURITY_PARTITION
1066 	TeecOperation.params[0].value.a = 0;
1067 #endif
1068 
1069 	TeecResult = TEEC_OpenSession(&TeecContext,
1070 				      &TeecSession,
1071 				      TeecUuid,
1072 				      TEEC_LOGIN_PUBLIC,
1073 				      NULL,
1074 					&TeecOperation,
1075 				      &ErrorOrigin);
1076 	if (TeecResult != TEEC_SUCCESS)
1077 		return TeecResult;
1078 
1079 	TEEC_SharedMemory SharedMem0 = {0};
1080 
1081 	SharedMem0.size = *operation_size;
1082 	SharedMem0.flags = 0;
1083 
1084 	TeecResult = TEEC_AllocateSharedMemory(&TeecContext, &SharedMem0);
1085 	if (TeecResult != TEEC_SUCCESS)
1086 		goto exit;
1087 
1088 	memcpy(SharedMem0.buffer, operation_start, SharedMem0.size);
1089 
1090 	TeecOperation.params[0].tmpref.buffer = SharedMem0.buffer;
1091 	TeecOperation.params[0].tmpref.size = SharedMem0.size;
1092 
1093 	TEEC_SharedMemory SharedMem1 = {0};
1094 
1095 	SharedMem1.size = *out_len;
1096 	SharedMem1.flags = 0;
1097 
1098 	TeecResult = TEEC_AllocateSharedMemory(&TeecContext, &SharedMem1);
1099 	if (TeecResult != TEEC_SUCCESS)
1100 		goto exit;
1101 
1102 	TeecOperation.params[1].tmpref.buffer = SharedMem1.buffer;
1103 	TeecOperation.params[1].tmpref.size = SharedMem1.size;
1104 
1105 	TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INOUT,
1106 						    TEEC_MEMREF_TEMP_INOUT,
1107 						    TEEC_NONE,
1108 						    TEEC_NONE);
1109 
1110 	TeecResult = TEEC_InvokeCommand(&TeecSession,
1111 					145,
1112 					&TeecOperation,
1113 					&ErrorOrigin);
1114 	if (TeecResult != TEEC_SUCCESS)
1115 		goto exit;
1116 
1117 	*out_len = TeecOperation.params[1].tmpref.size;
1118 	memcpy(out, SharedMem1.buffer, SharedMem1.size);
1119 exit:
1120 	TEEC_ReleaseSharedMemory(&SharedMem0);
1121 	TEEC_ReleaseSharedMemory(&SharedMem1);
1122 	TEEC_CloseSession(&TeecSession);
1123 	TEEC_FinalizeContext(&TeecContext);
1124 
1125 	return TeecResult;
1126 }
1127 
1128 uint32_t trusty_attest_set_ca(uint8_t *ca_response, uint32_t *ca_response_size)
1129 {
1130 	TEEC_Result TeecResult;
1131 	TEEC_Context TeecContext;
1132 	TEEC_Session TeecSession;
1133 	uint32_t ErrorOrigin;
1134 	TEEC_UUID tempuuid = { 0x258be795, 0xf9ca, 0x40e6,
1135 				{ 0xa8, 0x69, 0x9c, 0xe6,
1136 				  0x88, 0x6c, 0x5d, 0x5d
1137 				}
1138 			     };
1139 	TEEC_UUID *TeecUuid = &tempuuid;
1140 	TEEC_Operation TeecOperation = {0};
1141 	struct blk_desc *dev_desc;
1142 	dev_desc = rockchip_get_bootdev();
1143 	if (!dev_desc) {
1144 		printf("%s: dev_desc is NULL!\n", __func__);
1145 		return -TEEC_ERROR_GENERIC;
1146 	}
1147 	TeecResult = OpteeClientApiLibInitialize();
1148 	if (TeecResult != TEEC_SUCCESS)
1149 		return TeecResult;
1150 
1151 	TeecResult = TEEC_InitializeContext(NULL, &TeecContext);
1152 	if (TeecResult != TEEC_SUCCESS)
1153 		return TeecResult;
1154 
1155 	TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
1156 						TEEC_NONE,
1157 						TEEC_NONE,
1158 						TEEC_NONE);
1159 	/*0 nand or emmc "security" partition , 1 rpmb*/
1160 	if (dev_desc->if_type == IF_TYPE_MMC && dev_desc->devnum == 0)
1161 		TeecOperation.params[0].value.a = 1;
1162 	else
1163 		TeecOperation.params[0].value.a = 0;
1164 
1165 #ifdef CONFIG_OPTEE_ALWAYS_USE_SECURITY_PARTITION
1166 	TeecOperation.params[0].value.a = 0;
1167 #endif
1168 
1169 	TeecResult = TEEC_OpenSession(&TeecContext,
1170 					&TeecSession,
1171 					TeecUuid,
1172 					TEEC_LOGIN_PUBLIC,
1173 					NULL,
1174 					&TeecOperation,
1175 					&ErrorOrigin);
1176 	if (TeecResult != TEEC_SUCCESS)
1177 		return TeecResult;
1178 
1179 	TEEC_SharedMemory SharedMem0 = {0};
1180 
1181 	SharedMem0.size = *ca_response_size;
1182 	SharedMem0.flags = 0;
1183 
1184 	TeecResult = TEEC_AllocateSharedMemory(&TeecContext, &SharedMem0);
1185 	if (TeecResult != TEEC_SUCCESS)
1186 		goto exit;
1187 
1188 	memcpy(SharedMem0.buffer, ca_response, SharedMem0.size);
1189 
1190 	TeecOperation.params[0].tmpref.buffer = SharedMem0.buffer;
1191 	TeecOperation.params[0].tmpref.size = SharedMem0.size;
1192 
1193 	TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INOUT,
1194 						    TEEC_NONE,
1195 						    TEEC_NONE,
1196 						    TEEC_NONE);
1197 
1198 	TeecResult = TEEC_InvokeCommand(&TeecSession,
1199 					146,
1200 					&TeecOperation,
1201 					&ErrorOrigin);
1202 	if (TeecResult != TEEC_SUCCESS)
1203 		goto exit;
1204 exit:
1205 	TEEC_ReleaseSharedMemory(&SharedMem0);
1206 	TEEC_CloseSession(&TeecSession);
1207 	TEEC_FinalizeContext(&TeecContext);
1208 
1209 	return TeecResult;
1210 }
1211