xref: /optee_os/ta/pkcs11/src/entry.c (revision 208dec389c1d63353477a478f774ee701285772b)
1f8a3a2c4SEtienne Carriere // SPDX-License-Identifier: BSD-2-Clause
2f8a3a2c4SEtienne Carriere /*
3f8a3a2c4SEtienne Carriere  * Copyright (c) 2018-2020, Linaro Limited
4f8a3a2c4SEtienne Carriere  */
5f8a3a2c4SEtienne Carriere 
6*208dec38SEtienne Carriere #include <assert.h>
7f8a3a2c4SEtienne Carriere #include <compiler.h>
86ea5aa6cSEtienne Carriere #include <pkcs11_ta.h>
9f8a3a2c4SEtienne Carriere #include <tee_internal_api.h>
1060290f69SEtienne Carriere #include <tee_internal_api_extensions.h>
11d34f3266SEtienne Carriere #include <util.h>
1260290f69SEtienne Carriere 
1360290f69SEtienne Carriere #include "pkcs11_helpers.h"
14f8a3a2c4SEtienne Carriere 
15f8a3a2c4SEtienne Carriere TEE_Result TA_CreateEntryPoint(void)
16f8a3a2c4SEtienne Carriere {
17f8a3a2c4SEtienne Carriere 	return TEE_SUCCESS;
18f8a3a2c4SEtienne Carriere }
19f8a3a2c4SEtienne Carriere 
20f8a3a2c4SEtienne Carriere void TA_DestroyEntryPoint(void)
21f8a3a2c4SEtienne Carriere {
22f8a3a2c4SEtienne Carriere }
23f8a3a2c4SEtienne Carriere 
24f8a3a2c4SEtienne Carriere TEE_Result TA_OpenSessionEntryPoint(uint32_t __unused param_types,
25f8a3a2c4SEtienne Carriere 				    TEE_Param __unused params[4],
26f8a3a2c4SEtienne Carriere 				    void **session)
27f8a3a2c4SEtienne Carriere {
28f8a3a2c4SEtienne Carriere 	*session = NULL;
29f8a3a2c4SEtienne Carriere 
30f8a3a2c4SEtienne Carriere 	return TEE_SUCCESS;
31f8a3a2c4SEtienne Carriere }
32f8a3a2c4SEtienne Carriere 
33f8a3a2c4SEtienne Carriere void TA_CloseSessionEntryPoint(void *session __unused)
34f8a3a2c4SEtienne Carriere {
35f8a3a2c4SEtienne Carriere }
36f8a3a2c4SEtienne Carriere 
37f8a3a2c4SEtienne Carriere /*
386ea5aa6cSEtienne Carriere  * Entry point for invocation command PKCS11_CMD_PING
396ea5aa6cSEtienne Carriere  *
40*208dec38SEtienne Carriere  * Return a PKCS11_CKR_* value which is also loaded into the output param#0
416ea5aa6cSEtienne Carriere  */
42*208dec38SEtienne Carriere static uint32_t entry_ping(uint32_t ptypes, TEE_Param *params)
436ea5aa6cSEtienne Carriere {
44*208dec38SEtienne Carriere 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
45*208dec38SEtienne Carriere 						TEE_PARAM_TYPE_NONE,
46*208dec38SEtienne Carriere 						TEE_PARAM_TYPE_MEMREF_OUTPUT,
47*208dec38SEtienne Carriere 						TEE_PARAM_TYPE_NONE);
48*208dec38SEtienne Carriere 	TEE_Param *out = &params[2];
496ea5aa6cSEtienne Carriere 	const uint32_t ver[] = {
506ea5aa6cSEtienne Carriere 		PKCS11_TA_VERSION_MAJOR,
516ea5aa6cSEtienne Carriere 		PKCS11_TA_VERSION_MINOR,
526ea5aa6cSEtienne Carriere 		PKCS11_TA_VERSION_PATCH,
536ea5aa6cSEtienne Carriere 	};
546ea5aa6cSEtienne Carriere 
55*208dec38SEtienne Carriere 	if (ptypes != exp_pt ||
56*208dec38SEtienne Carriere 	    params[0].memref.size != TEE_PARAM0_SIZE_MIN ||
57*208dec38SEtienne Carriere 	    out->memref.size != sizeof(ver))
58*208dec38SEtienne Carriere 		return PKCS11_CKR_ARGUMENTS_BAD;
596ea5aa6cSEtienne Carriere 
606ea5aa6cSEtienne Carriere 	TEE_MemMove(out->memref.buffer, ver, sizeof(ver));
616ea5aa6cSEtienne Carriere 
62d34f3266SEtienne Carriere 	return PKCS11_CKR_OK;
636ea5aa6cSEtienne Carriere }
646ea5aa6cSEtienne Carriere 
65*208dec38SEtienne Carriere static bool __maybe_unused param_is_none(uint32_t ptypes, unsigned int index)
66*208dec38SEtienne Carriere {
67*208dec38SEtienne Carriere 	return TEE_PARAM_TYPE_GET(ptypes, index) ==
68*208dec38SEtienne Carriere 	       TEE_PARAM_TYPE_NONE;
69*208dec38SEtienne Carriere }
70*208dec38SEtienne Carriere 
71*208dec38SEtienne Carriere static bool __maybe_unused param_is_memref(uint32_t ptypes, unsigned int index)
72*208dec38SEtienne Carriere {
73*208dec38SEtienne Carriere 	switch (TEE_PARAM_TYPE_GET(ptypes, index)) {
74*208dec38SEtienne Carriere 	case TEE_PARAM_TYPE_MEMREF_INPUT:
75*208dec38SEtienne Carriere 	case TEE_PARAM_TYPE_MEMREF_OUTPUT:
76*208dec38SEtienne Carriere 	case TEE_PARAM_TYPE_MEMREF_INOUT:
77*208dec38SEtienne Carriere 		return true;
78*208dec38SEtienne Carriere 	default:
79*208dec38SEtienne Carriere 		return false;
80*208dec38SEtienne Carriere 	}
81*208dec38SEtienne Carriere }
82*208dec38SEtienne Carriere 
83*208dec38SEtienne Carriere static bool __maybe_unused param_is_input(uint32_t ptypes, unsigned int index)
84*208dec38SEtienne Carriere {
85*208dec38SEtienne Carriere 	return TEE_PARAM_TYPE_GET(ptypes, index) ==
86*208dec38SEtienne Carriere 	       TEE_PARAM_TYPE_MEMREF_INPUT;
87*208dec38SEtienne Carriere }
88*208dec38SEtienne Carriere 
89*208dec38SEtienne Carriere static bool __maybe_unused param_is_output(uint32_t ptypes, unsigned int index)
90*208dec38SEtienne Carriere {
91*208dec38SEtienne Carriere 	return TEE_PARAM_TYPE_GET(ptypes, index) ==
92*208dec38SEtienne Carriere 	       TEE_PARAM_TYPE_MEMREF_OUTPUT;
93*208dec38SEtienne Carriere }
94*208dec38SEtienne Carriere 
956ea5aa6cSEtienne Carriere /*
96f8a3a2c4SEtienne Carriere  * Entry point for PKCS11 TA commands
97*208dec38SEtienne Carriere  *
98*208dec38SEtienne Carriere  * Param#0 (ctrl) is an output or an in/out buffer. Input data are serialized
99*208dec38SEtienne Carriere  * arguments for the invoked command while the output data is used to send
100*208dec38SEtienne Carriere  * back to the client a PKCS11 finer status ID than the GPD TEE result codes
101*208dec38SEtienne Carriere  * Client shall check the status ID from the parameter #0 output buffer together
102*208dec38SEtienne Carriere  * with the GPD TEE result code.
103f8a3a2c4SEtienne Carriere  */
104f8a3a2c4SEtienne Carriere TEE_Result TA_InvokeCommandEntryPoint(void *tee_session __unused, uint32_t cmd,
1056ea5aa6cSEtienne Carriere 				      uint32_t ptypes,
1066ea5aa6cSEtienne Carriere 				      TEE_Param params[TEE_NUM_PARAMS])
107f8a3a2c4SEtienne Carriere {
108d34f3266SEtienne Carriere 	uint32_t rc = 0;
109f8a3a2c4SEtienne Carriere 
110*208dec38SEtienne Carriere 	/* All command handlers will check only against 4 parameters */
111*208dec38SEtienne Carriere 	COMPILE_TIME_ASSERT(TEE_NUM_PARAMS == 4);
112*208dec38SEtienne Carriere 
113*208dec38SEtienne Carriere 	/*
114*208dec38SEtienne Carriere 	 * Param#0 must be either an output or an inout memref as used to
115*208dec38SEtienne Carriere 	 * store the output return value for the invoked command.
116*208dec38SEtienne Carriere 	 */
1176ea5aa6cSEtienne Carriere 	switch (TEE_PARAM_TYPE_GET(ptypes, 0)) {
1186ea5aa6cSEtienne Carriere 	case TEE_PARAM_TYPE_MEMREF_OUTPUT:
119*208dec38SEtienne Carriere 	case TEE_PARAM_TYPE_MEMREF_INOUT:
120*208dec38SEtienne Carriere 		if (params[0].memref.size < sizeof(uint32_t))
121*208dec38SEtienne Carriere 			return TEE_ERROR_BAD_PARAMETERS;
1226ea5aa6cSEtienne Carriere 		break;
1236ea5aa6cSEtienne Carriere 	default:
1246ea5aa6cSEtienne Carriere 		return TEE_ERROR_BAD_PARAMETERS;
1256ea5aa6cSEtienne Carriere 	}
1266ea5aa6cSEtienne Carriere 
127*208dec38SEtienne Carriere 	DMSG("%s p#0 %"PRIu32"@%p, p#1 %s %"PRIu32"@%p, p#2 %s %"PRIu32"@%p",
12860290f69SEtienne Carriere 	     id2str_ta_cmd(cmd),
129*208dec38SEtienne Carriere 	     params[0].memref.size, params[0].memref.buffer,
130*208dec38SEtienne Carriere 	     param_is_input(ptypes, 1) ? "in" :
131*208dec38SEtienne Carriere 	     param_is_output(ptypes, 1) ? "out" : "---",
132*208dec38SEtienne Carriere 	     param_is_memref(ptypes, 1) ? params[1].memref.size : 0,
133*208dec38SEtienne Carriere 	     param_is_memref(ptypes, 1) ? params[1].memref.buffer : NULL,
134*208dec38SEtienne Carriere 	     param_is_input(ptypes, 2) ? "in" :
135*208dec38SEtienne Carriere 	     param_is_output(ptypes, 2) ? "out" : "---",
136*208dec38SEtienne Carriere 	     param_is_memref(ptypes, 2) ? params[2].memref.size : 0,
137*208dec38SEtienne Carriere 	     param_is_memref(ptypes, 2) ? params[2].memref.buffer : NULL);
13860290f69SEtienne Carriere 
1396ea5aa6cSEtienne Carriere 	switch (cmd) {
1406ea5aa6cSEtienne Carriere 	case PKCS11_CMD_PING:
141*208dec38SEtienne Carriere 		rc = entry_ping(ptypes, params);
1426ea5aa6cSEtienne Carriere 		break;
1436ea5aa6cSEtienne Carriere 
1446ea5aa6cSEtienne Carriere 	default:
1456ea5aa6cSEtienne Carriere 		EMSG("Command 0x%"PRIx32" is not supported", cmd);
146f8a3a2c4SEtienne Carriere 		return TEE_ERROR_NOT_SUPPORTED;
147f8a3a2c4SEtienne Carriere 	}
1486ea5aa6cSEtienne Carriere 
149*208dec38SEtienne Carriere 	DMSG("%s rc 0x%08"PRIx32"/%s", id2str_ta_cmd(cmd), rc, id2str_rc(rc));
1506ea5aa6cSEtienne Carriere 
151*208dec38SEtienne Carriere 	TEE_MemMove(params[0].memref.buffer, &rc, sizeof(rc));
152*208dec38SEtienne Carriere 	params[0].memref.size = sizeof(rc);
153d34f3266SEtienne Carriere 
154*208dec38SEtienne Carriere 	if (rc == PKCS11_CKR_BUFFER_TOO_SMALL)
155*208dec38SEtienne Carriere 		return TEE_ERROR_SHORT_BUFFER;
156*208dec38SEtienne Carriere 	else
157*208dec38SEtienne Carriere 		return TEE_SUCCESS;
1586ea5aa6cSEtienne Carriere }
159