xref: /optee_os/core/pta/apdu.c (revision b0e1c5e485b7f19870af461662a127f39a793e72)
1*b0e1c5e4SJorge Ramirez-Ortiz // SPDX-License-Identifier: BSD-2-Clause
2*b0e1c5e4SJorge Ramirez-Ortiz /*
3*b0e1c5e4SJorge Ramirez-Ortiz  * Copyright (C) Foundries Ltd. 2021 - All Rights Reserved
4*b0e1c5e4SJorge Ramirez-Ortiz  * Author: Jorge Ramirez <jorge@foundries.io>
5*b0e1c5e4SJorge Ramirez-Ortiz  */
6*b0e1c5e4SJorge Ramirez-Ortiz #include <crypto/crypto_se.h>
7*b0e1c5e4SJorge Ramirez-Ortiz #include <kernel/pseudo_ta.h>
8*b0e1c5e4SJorge Ramirez-Ortiz #include <pta_apdu.h>
9*b0e1c5e4SJorge Ramirez-Ortiz 
10*b0e1c5e4SJorge Ramirez-Ortiz #define PTA_NAME "pta.apdu"
11*b0e1c5e4SJorge Ramirez-Ortiz 
get_apdu_type(uint32_t val,enum crypto_apdu_type * type)12*b0e1c5e4SJorge Ramirez-Ortiz static TEE_Result get_apdu_type(uint32_t val, enum crypto_apdu_type *type)
13*b0e1c5e4SJorge Ramirez-Ortiz {
14*b0e1c5e4SJorge Ramirez-Ortiz 	switch (val) {
15*b0e1c5e4SJorge Ramirez-Ortiz 	case PTA_APDU_TXRX_CASE_NO_HINT:
16*b0e1c5e4SJorge Ramirez-Ortiz 		*type = CRYPTO_APDU_CASE_NO_HINT;
17*b0e1c5e4SJorge Ramirez-Ortiz 		break;
18*b0e1c5e4SJorge Ramirez-Ortiz 	case PTA_APDU_TXRX_CASE_1:
19*b0e1c5e4SJorge Ramirez-Ortiz 		*type = CRYPTO_APDU_CASE_1;
20*b0e1c5e4SJorge Ramirez-Ortiz 		break;
21*b0e1c5e4SJorge Ramirez-Ortiz 	case PTA_APDU_TXRX_CASE_2:
22*b0e1c5e4SJorge Ramirez-Ortiz 		*type = CRYPTO_APDU_CASE_2;
23*b0e1c5e4SJorge Ramirez-Ortiz 		break;
24*b0e1c5e4SJorge Ramirez-Ortiz 	case PTA_APDU_TXRX_CASE_2E:
25*b0e1c5e4SJorge Ramirez-Ortiz 		*type = CRYPTO_APDU_CASE_2E;
26*b0e1c5e4SJorge Ramirez-Ortiz 		break;
27*b0e1c5e4SJorge Ramirez-Ortiz 	case PTA_APDU_TXRX_CASE_3:
28*b0e1c5e4SJorge Ramirez-Ortiz 		*type = CRYPTO_APDU_CASE_3;
29*b0e1c5e4SJorge Ramirez-Ortiz 		break;
30*b0e1c5e4SJorge Ramirez-Ortiz 	case PTA_APDU_TXRX_CASE_3E:
31*b0e1c5e4SJorge Ramirez-Ortiz 		*type = CRYPTO_APDU_CASE_3E;
32*b0e1c5e4SJorge Ramirez-Ortiz 		break;
33*b0e1c5e4SJorge Ramirez-Ortiz 	case PTA_APDU_TXRX_CASE_4:
34*b0e1c5e4SJorge Ramirez-Ortiz 		*type = CRYPTO_APDU_CASE_4;
35*b0e1c5e4SJorge Ramirez-Ortiz 		break;
36*b0e1c5e4SJorge Ramirez-Ortiz 	case PTA_APDU_TXRX_CASE_4E:
37*b0e1c5e4SJorge Ramirez-Ortiz 		*type = CRYPTO_APDU_CASE_4E;
38*b0e1c5e4SJorge Ramirez-Ortiz 		break;
39*b0e1c5e4SJorge Ramirez-Ortiz 	default:
40*b0e1c5e4SJorge Ramirez-Ortiz 		return TEE_ERROR_BAD_PARAMETERS;
41*b0e1c5e4SJorge Ramirez-Ortiz 	}
42*b0e1c5e4SJorge Ramirez-Ortiz 	return TEE_SUCCESS;
43*b0e1c5e4SJorge Ramirez-Ortiz }
44*b0e1c5e4SJorge Ramirez-Ortiz 
invoke_command(void * session_context __unused,uint32_t command_id,uint32_t pt,TEE_Param params[TEE_NUM_PARAMS])45*b0e1c5e4SJorge Ramirez-Ortiz static TEE_Result invoke_command(void *session_context __unused,
46*b0e1c5e4SJorge Ramirez-Ortiz 				 uint32_t command_id, uint32_t pt,
47*b0e1c5e4SJorge Ramirez-Ortiz 				 TEE_Param params[TEE_NUM_PARAMS])
48*b0e1c5e4SJorge Ramirez-Ortiz {
49*b0e1c5e4SJorge Ramirez-Ortiz 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
50*b0e1c5e4SJorge Ramirez-Ortiz 						TEE_PARAM_TYPE_MEMREF_INPUT,
51*b0e1c5e4SJorge Ramirez-Ortiz 						TEE_PARAM_TYPE_MEMREF_INPUT,
52*b0e1c5e4SJorge Ramirez-Ortiz 						TEE_PARAM_TYPE_MEMREF_OUTPUT);
53*b0e1c5e4SJorge Ramirez-Ortiz 	enum crypto_apdu_type type = CRYPTO_APDU_CASE_NO_HINT;
54*b0e1c5e4SJorge Ramirez-Ortiz 	TEE_Result ret = TEE_ERROR_NOT_IMPLEMENTED;
55*b0e1c5e4SJorge Ramirez-Ortiz 	size_t len = 0;
56*b0e1c5e4SJorge Ramirez-Ortiz 
57*b0e1c5e4SJorge Ramirez-Ortiz 	FMSG("command entry point for pseudo-TA \"%s\"", PTA_NAME);
58*b0e1c5e4SJorge Ramirez-Ortiz 
59*b0e1c5e4SJorge Ramirez-Ortiz 	if (pt != exp_pt)
60*b0e1c5e4SJorge Ramirez-Ortiz 		return TEE_ERROR_BAD_PARAMETERS;
61*b0e1c5e4SJorge Ramirez-Ortiz 
62*b0e1c5e4SJorge Ramirez-Ortiz 	switch (command_id) {
63*b0e1c5e4SJorge Ramirez-Ortiz 	case PTA_CMD_TXRX_APDU_RAW_FRAME:
64*b0e1c5e4SJorge Ramirez-Ortiz 		ret = get_apdu_type(params[0].value.a, &type);
65*b0e1c5e4SJorge Ramirez-Ortiz 		if (ret)
66*b0e1c5e4SJorge Ramirez-Ortiz 			return ret;
67*b0e1c5e4SJorge Ramirez-Ortiz 
68*b0e1c5e4SJorge Ramirez-Ortiz 		len = params[3].memref.size;
69*b0e1c5e4SJorge Ramirez-Ortiz 		ret = crypto_se_do_apdu(type,
70*b0e1c5e4SJorge Ramirez-Ortiz 					params[1].memref.buffer,
71*b0e1c5e4SJorge Ramirez-Ortiz 					params[1].memref.size,
72*b0e1c5e4SJorge Ramirez-Ortiz 					params[2].memref.buffer,
73*b0e1c5e4SJorge Ramirez-Ortiz 					params[2].memref.size,
74*b0e1c5e4SJorge Ramirez-Ortiz 					params[3].memref.buffer,
75*b0e1c5e4SJorge Ramirez-Ortiz 					&len);
76*b0e1c5e4SJorge Ramirez-Ortiz 		if (!ret)
77*b0e1c5e4SJorge Ramirez-Ortiz 			params[3].memref.size = len;
78*b0e1c5e4SJorge Ramirez-Ortiz 		break;
79*b0e1c5e4SJorge Ramirez-Ortiz 	default:
80*b0e1c5e4SJorge Ramirez-Ortiz 		return TEE_ERROR_NOT_IMPLEMENTED;
81*b0e1c5e4SJorge Ramirez-Ortiz 	}
82*b0e1c5e4SJorge Ramirez-Ortiz 
83*b0e1c5e4SJorge Ramirez-Ortiz 	return ret;
84*b0e1c5e4SJorge Ramirez-Ortiz }
85*b0e1c5e4SJorge Ramirez-Ortiz 
86*b0e1c5e4SJorge Ramirez-Ortiz pseudo_ta_register(.uuid = PTA_APDU_UUID, .name = PTA_NAME,
87*b0e1c5e4SJorge Ramirez-Ortiz 		   .flags = PTA_DEFAULT_FLAGS,
88*b0e1c5e4SJorge Ramirez-Ortiz 		   .invoke_command_entry_point = invoke_command);
89