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