xref: /optee_os/ta/pkcs11/src/entry.c (revision ce94efefb619f4d10aa95e81c2fe02a7dd03b753)
1f8a3a2c4SEtienne Carriere // SPDX-License-Identifier: BSD-2-Clause
2f8a3a2c4SEtienne Carriere /*
3f8a3a2c4SEtienne Carriere  * Copyright (c) 2018-2020, Linaro Limited
4f8a3a2c4SEtienne Carriere  */
5f8a3a2c4SEtienne Carriere 
6208dec38SEtienne 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"
14c84ccd0aSEtienne Carriere #include "pkcs11_token.h"
15f8a3a2c4SEtienne Carriere 
16f8a3a2c4SEtienne Carriere TEE_Result TA_CreateEntryPoint(void)
17f8a3a2c4SEtienne Carriere {
18c84ccd0aSEtienne Carriere 	return pkcs11_init();
19f8a3a2c4SEtienne Carriere }
20f8a3a2c4SEtienne Carriere 
21f8a3a2c4SEtienne Carriere void TA_DestroyEntryPoint(void)
22f8a3a2c4SEtienne Carriere {
23c84ccd0aSEtienne Carriere 	pkcs11_deinit();
24f8a3a2c4SEtienne Carriere }
25f8a3a2c4SEtienne Carriere 
26f8a3a2c4SEtienne Carriere TEE_Result TA_OpenSessionEntryPoint(uint32_t __unused param_types,
27f8a3a2c4SEtienne Carriere 				    TEE_Param __unused params[4],
28f8a3a2c4SEtienne Carriere 				    void **session)
29f8a3a2c4SEtienne Carriere {
30f8a3a2c4SEtienne Carriere 	*session = NULL;
31f8a3a2c4SEtienne Carriere 
32f8a3a2c4SEtienne Carriere 	return TEE_SUCCESS;
33f8a3a2c4SEtienne Carriere }
34f8a3a2c4SEtienne Carriere 
35f8a3a2c4SEtienne Carriere void TA_CloseSessionEntryPoint(void *session __unused)
36f8a3a2c4SEtienne Carriere {
37f8a3a2c4SEtienne Carriere }
38f8a3a2c4SEtienne Carriere 
39f8a3a2c4SEtienne Carriere /*
406ea5aa6cSEtienne Carriere  * Entry point for invocation command PKCS11_CMD_PING
416ea5aa6cSEtienne Carriere  *
42208dec38SEtienne Carriere  * Return a PKCS11_CKR_* value which is also loaded into the output param#0
436ea5aa6cSEtienne Carriere  */
44208dec38SEtienne Carriere static uint32_t entry_ping(uint32_t ptypes, TEE_Param *params)
456ea5aa6cSEtienne Carriere {
46208dec38SEtienne Carriere 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
47208dec38SEtienne Carriere 						TEE_PARAM_TYPE_NONE,
48208dec38SEtienne Carriere 						TEE_PARAM_TYPE_MEMREF_OUTPUT,
49208dec38SEtienne Carriere 						TEE_PARAM_TYPE_NONE);
50208dec38SEtienne Carriere 	TEE_Param *out = &params[2];
516ea5aa6cSEtienne Carriere 	const uint32_t ver[] = {
526ea5aa6cSEtienne Carriere 		PKCS11_TA_VERSION_MAJOR,
536ea5aa6cSEtienne Carriere 		PKCS11_TA_VERSION_MINOR,
546ea5aa6cSEtienne Carriere 		PKCS11_TA_VERSION_PATCH,
556ea5aa6cSEtienne Carriere 	};
566ea5aa6cSEtienne Carriere 
57208dec38SEtienne Carriere 	if (ptypes != exp_pt ||
58208dec38SEtienne Carriere 	    params[0].memref.size != TEE_PARAM0_SIZE_MIN ||
59208dec38SEtienne Carriere 	    out->memref.size != sizeof(ver))
60208dec38SEtienne Carriere 		return PKCS11_CKR_ARGUMENTS_BAD;
616ea5aa6cSEtienne Carriere 
626ea5aa6cSEtienne Carriere 	TEE_MemMove(out->memref.buffer, ver, sizeof(ver));
636ea5aa6cSEtienne Carriere 
64d34f3266SEtienne Carriere 	return PKCS11_CKR_OK;
656ea5aa6cSEtienne Carriere }
666ea5aa6cSEtienne Carriere 
67208dec38SEtienne Carriere static bool __maybe_unused param_is_none(uint32_t ptypes, unsigned int index)
68208dec38SEtienne Carriere {
69208dec38SEtienne Carriere 	return TEE_PARAM_TYPE_GET(ptypes, index) ==
70208dec38SEtienne Carriere 	       TEE_PARAM_TYPE_NONE;
71208dec38SEtienne Carriere }
72208dec38SEtienne Carriere 
73208dec38SEtienne Carriere static bool __maybe_unused param_is_memref(uint32_t ptypes, unsigned int index)
74208dec38SEtienne Carriere {
75208dec38SEtienne Carriere 	switch (TEE_PARAM_TYPE_GET(ptypes, index)) {
76208dec38SEtienne Carriere 	case TEE_PARAM_TYPE_MEMREF_INPUT:
77208dec38SEtienne Carriere 	case TEE_PARAM_TYPE_MEMREF_OUTPUT:
78208dec38SEtienne Carriere 	case TEE_PARAM_TYPE_MEMREF_INOUT:
79208dec38SEtienne Carriere 		return true;
80208dec38SEtienne Carriere 	default:
81208dec38SEtienne Carriere 		return false;
82208dec38SEtienne Carriere 	}
83208dec38SEtienne Carriere }
84208dec38SEtienne Carriere 
85208dec38SEtienne Carriere static bool __maybe_unused param_is_input(uint32_t ptypes, unsigned int index)
86208dec38SEtienne Carriere {
87208dec38SEtienne Carriere 	return TEE_PARAM_TYPE_GET(ptypes, index) ==
88208dec38SEtienne Carriere 	       TEE_PARAM_TYPE_MEMREF_INPUT;
89208dec38SEtienne Carriere }
90208dec38SEtienne Carriere 
91208dec38SEtienne Carriere static bool __maybe_unused param_is_output(uint32_t ptypes, unsigned int index)
92208dec38SEtienne Carriere {
93208dec38SEtienne Carriere 	return TEE_PARAM_TYPE_GET(ptypes, index) ==
94208dec38SEtienne Carriere 	       TEE_PARAM_TYPE_MEMREF_OUTPUT;
95208dec38SEtienne Carriere }
96208dec38SEtienne Carriere 
976ea5aa6cSEtienne Carriere /*
98f8a3a2c4SEtienne Carriere  * Entry point for PKCS11 TA commands
99208dec38SEtienne Carriere  *
100208dec38SEtienne Carriere  * Param#0 (ctrl) is an output or an in/out buffer. Input data are serialized
101208dec38SEtienne Carriere  * arguments for the invoked command while the output data is used to send
102208dec38SEtienne Carriere  * back to the client a PKCS11 finer status ID than the GPD TEE result codes
103208dec38SEtienne Carriere  * Client shall check the status ID from the parameter #0 output buffer together
104208dec38SEtienne Carriere  * with the GPD TEE result code.
105f8a3a2c4SEtienne Carriere  */
106f8a3a2c4SEtienne Carriere TEE_Result TA_InvokeCommandEntryPoint(void *tee_session __unused, uint32_t cmd,
1076ea5aa6cSEtienne Carriere 				      uint32_t ptypes,
1086ea5aa6cSEtienne Carriere 				      TEE_Param params[TEE_NUM_PARAMS])
109f8a3a2c4SEtienne Carriere {
110d34f3266SEtienne Carriere 	uint32_t rc = 0;
111f8a3a2c4SEtienne Carriere 
112208dec38SEtienne Carriere 	/* All command handlers will check only against 4 parameters */
113208dec38SEtienne Carriere 	COMPILE_TIME_ASSERT(TEE_NUM_PARAMS == 4);
114208dec38SEtienne Carriere 
115208dec38SEtienne Carriere 	/*
116208dec38SEtienne Carriere 	 * Param#0 must be either an output or an inout memref as used to
117208dec38SEtienne Carriere 	 * store the output return value for the invoked command.
118208dec38SEtienne Carriere 	 */
1196ea5aa6cSEtienne Carriere 	switch (TEE_PARAM_TYPE_GET(ptypes, 0)) {
1206ea5aa6cSEtienne Carriere 	case TEE_PARAM_TYPE_MEMREF_OUTPUT:
121208dec38SEtienne Carriere 	case TEE_PARAM_TYPE_MEMREF_INOUT:
122208dec38SEtienne Carriere 		if (params[0].memref.size < sizeof(uint32_t))
123208dec38SEtienne Carriere 			return TEE_ERROR_BAD_PARAMETERS;
1246ea5aa6cSEtienne Carriere 		break;
1256ea5aa6cSEtienne Carriere 	default:
1266ea5aa6cSEtienne Carriere 		return TEE_ERROR_BAD_PARAMETERS;
1276ea5aa6cSEtienne Carriere 	}
1286ea5aa6cSEtienne Carriere 
129208dec38SEtienne Carriere 	DMSG("%s p#0 %"PRIu32"@%p, p#1 %s %"PRIu32"@%p, p#2 %s %"PRIu32"@%p",
13060290f69SEtienne Carriere 	     id2str_ta_cmd(cmd),
131208dec38SEtienne Carriere 	     params[0].memref.size, params[0].memref.buffer,
132208dec38SEtienne Carriere 	     param_is_input(ptypes, 1) ? "in" :
133208dec38SEtienne Carriere 	     param_is_output(ptypes, 1) ? "out" : "---",
134208dec38SEtienne Carriere 	     param_is_memref(ptypes, 1) ? params[1].memref.size : 0,
135208dec38SEtienne Carriere 	     param_is_memref(ptypes, 1) ? params[1].memref.buffer : NULL,
136208dec38SEtienne Carriere 	     param_is_input(ptypes, 2) ? "in" :
137208dec38SEtienne Carriere 	     param_is_output(ptypes, 2) ? "out" : "---",
138208dec38SEtienne Carriere 	     param_is_memref(ptypes, 2) ? params[2].memref.size : 0,
139208dec38SEtienne Carriere 	     param_is_memref(ptypes, 2) ? params[2].memref.buffer : NULL);
14060290f69SEtienne Carriere 
1416ea5aa6cSEtienne Carriere 	switch (cmd) {
1426ea5aa6cSEtienne Carriere 	case PKCS11_CMD_PING:
143208dec38SEtienne Carriere 		rc = entry_ping(ptypes, params);
1446ea5aa6cSEtienne Carriere 		break;
1456ea5aa6cSEtienne Carriere 
14622ac6984SEtienne Carriere 	case PKCS11_CMD_SLOT_LIST:
14722ac6984SEtienne Carriere 		rc = entry_ck_slot_list(ptypes, params);
14822ac6984SEtienne Carriere 		break;
149*ce94efefSEtienne Carriere 	case PKCS11_CMD_SLOT_INFO:
150*ce94efefSEtienne Carriere 		rc = entry_ck_slot_info(ptypes, params);
151*ce94efefSEtienne Carriere 		break;
1526ea5aa6cSEtienne Carriere 	default:
1536ea5aa6cSEtienne Carriere 		EMSG("Command 0x%"PRIx32" is not supported", cmd);
154f8a3a2c4SEtienne Carriere 		return TEE_ERROR_NOT_SUPPORTED;
155f8a3a2c4SEtienne Carriere 	}
1566ea5aa6cSEtienne Carriere 
157208dec38SEtienne Carriere 	DMSG("%s rc 0x%08"PRIx32"/%s", id2str_ta_cmd(cmd), rc, id2str_rc(rc));
1586ea5aa6cSEtienne Carriere 
159208dec38SEtienne Carriere 	TEE_MemMove(params[0].memref.buffer, &rc, sizeof(rc));
160208dec38SEtienne Carriere 	params[0].memref.size = sizeof(rc);
161d34f3266SEtienne Carriere 
162208dec38SEtienne Carriere 	if (rc == PKCS11_CKR_BUFFER_TOO_SMALL)
163208dec38SEtienne Carriere 		return TEE_ERROR_SHORT_BUFFER;
164208dec38SEtienne Carriere 	else
165208dec38SEtienne Carriere 		return TEE_SUCCESS;
1666ea5aa6cSEtienne Carriere }
167