1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright 2018-2019, 2023 NXP
4  */
5 #include <drivers/caam_extension.h>
6 #include <kernel/pseudo_ta.h>
7 #include <kernel/user_ta.h>
8 #include <pta_imx_manufacturing_protection.h>
9 #include <stdint.h>
10 #include <string.h>
11 #include <tee_api_types.h>
12 
13 #define PTA_NAME "manufacturing_protection.pta"
14 
mp_get_public_key(uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])15 static TEE_Result mp_get_public_key(uint32_t param_types,
16 				    TEE_Param params[TEE_NUM_PARAMS])
17 {
18 	uint8_t *data = NULL;
19 	size_t size = 0;
20 	TEE_Result res = TEE_ERROR_GENERIC;
21 	uint32_t exp_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_OUTPUT,
22 						   TEE_PARAM_TYPE_NONE,
23 						   TEE_PARAM_TYPE_NONE,
24 						   TEE_PARAM_TYPE_NONE);
25 
26 	if (param_types != exp_param_types)
27 		return TEE_ERROR_BAD_PARAMETERS;
28 
29 	data = params[0].memref.buffer;
30 	size = params[0].memref.size;
31 
32 	res = caam_mp_export_publickey(data, &size);
33 	if (res != TEE_SUCCESS)
34 		EMSG("MP public key export failed with code 0x%" PRIx32, res);
35 
36 	params[0].memref.size = size;
37 	return res;
38 }
39 
mp_signature(uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])40 static TEE_Result mp_signature(uint32_t param_types,
41 			       TEE_Param params[TEE_NUM_PARAMS])
42 {
43 	TEE_Result res = TEE_ERROR_GENERIC;
44 	uint8_t *msg = NULL;
45 	uint8_t *sig = NULL;
46 	uint8_t *mpmr = NULL;
47 	size_t msg_size = 0;
48 	size_t sig_size = 0;
49 	size_t mpmr_size = 0;
50 	uint32_t exp_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
51 						   TEE_PARAM_TYPE_MEMREF_OUTPUT,
52 						   TEE_PARAM_TYPE_MEMREF_OUTPUT,
53 						   TEE_PARAM_TYPE_NONE);
54 
55 	if (param_types != exp_param_types)
56 		return TEE_ERROR_BAD_PARAMETERS;
57 
58 	DMSG("MPSign function");
59 
60 	msg = params[0].memref.buffer;
61 	msg_size = params[0].memref.size;
62 	sig = params[1].memref.buffer;
63 	sig_size = params[1].memref.size;
64 	mpmr = params[2].memref.buffer;
65 	mpmr_size = params[2].memref.size;
66 
67 	memset(sig, 0, sig_size);
68 	memset(mpmr, 0, mpmr_size);
69 
70 	res = caam_mp_sign(msg, &msg_size, sig, &sig_size);
71 
72 	params[1].memref.size = sig_size;
73 
74 	if (res != TEE_SUCCESS) {
75 		EMSG("Manufacturing Protection signature failed 0x%" PRIx32,
76 		     res);
77 		return res;
78 	}
79 
80 	res = caam_mp_export_mpmr(mpmr, &mpmr_size);
81 
82 	params[2].memref.size = mpmr_size;
83 
84 	if (res != TEE_SUCCESS)
85 		EMSG("Manufacturing Protection export MPRM failed 0x%" PRIx32,
86 		     res);
87 
88 	return res;
89 }
90 
91 static TEE_Result
pta_mp_open_session(uint32_t param_types __unused,TEE_Param params[TEE_NUM_PARAMS]__unused,void ** sess_ctx __unused)92 pta_mp_open_session(uint32_t param_types __unused,
93 		    TEE_Param params[TEE_NUM_PARAMS] __unused,
94 		    void **sess_ctx __unused)
95 {
96 	struct ts_session *s = NULL;
97 
98 	if (IS_ENABLED(CFG_NXP_CAAM_MP_NO_ACCESS_CTRL))
99 		return TEE_SUCCESS;
100 
101 	s = ts_get_calling_session();
102 	if (!s || !is_user_ta_ctx(s->ctx))
103 		return TEE_ERROR_ACCESS_DENIED;
104 
105 	return TEE_SUCCESS;
106 }
107 
pta_mp_invoke_cmd(void * sess_ctx __unused,uint32_t cmd_id,uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])108 static TEE_Result pta_mp_invoke_cmd(void *sess_ctx __unused,
109 				    uint32_t cmd_id, uint32_t param_types,
110 				    TEE_Param params[TEE_NUM_PARAMS])
111 {
112 	switch (cmd_id) {
113 	case PTA_IMX_MP_CMD_SIGNATURE_MPMR:
114 		return mp_signature(param_types, params);
115 	case PTA_IMX_MP_CMD_GET_PUBLIC_KEY:
116 		return mp_get_public_key(param_types, params);
117 	default:
118 		return TEE_ERROR_BAD_PARAMETERS;
119 	}
120 }
121 
122 pseudo_ta_register(.uuid = PTA_MANUFACT_PROTEC_UUID, .name = PTA_NAME,
123 		   .flags = PTA_DEFAULT_FLAGS,
124 		   .open_session_entry_point = pta_mp_open_session,
125 		   .invoke_command_entry_point = pta_mp_invoke_cmd);
126