1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2018, Linaro Limited
4  */
5 
6 #include <inttypes.h>
7 
8 #include <tee_internal_api.h>
9 
10 #include <acipher_ta.h>
11 
12 struct acipher {
13 	TEE_ObjectHandle key;
14 };
15 
cmd_gen_key(struct acipher * state,uint32_t pt,TEE_Param params[TEE_NUM_PARAMS])16 static TEE_Result cmd_gen_key(struct acipher *state, uint32_t pt,
17 			      TEE_Param params[TEE_NUM_PARAMS])
18 {
19 	TEE_Result res;
20 	uint32_t key_size;
21 	TEE_ObjectHandle key;
22 	const uint32_t key_type = TEE_TYPE_RSA_KEYPAIR;
23 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
24 						TEE_PARAM_TYPE_NONE,
25 						TEE_PARAM_TYPE_NONE,
26 						TEE_PARAM_TYPE_NONE);
27 
28 	if (pt != exp_pt)
29 		return TEE_ERROR_BAD_PARAMETERS;
30 
31 	key_size = params[0].value.a;
32 
33 	res = TEE_AllocateTransientObject(key_type, key_size, &key);
34 	if (res) {
35 		EMSG("TEE_AllocateTransientObject(%#" PRIx32 ", %" PRId32 "): %#" PRIx32, key_type, key_size, res);
36 		return res;
37 	}
38 
39 	res = TEE_GenerateKey(key, key_size, NULL, 0);
40 	if (res) {
41 		EMSG("TEE_GenerateKey(%" PRId32 "): %#" PRIx32,
42 		     key_size, res);
43 		TEE_FreeTransientObject(key);
44 		return res;
45 	}
46 
47 	TEE_FreeTransientObject(state->key);
48 	state->key = key;
49 	return TEE_SUCCESS;
50 }
51 
cmd_enc(struct acipher * state,uint32_t pt,TEE_Param params[TEE_NUM_PARAMS])52 static TEE_Result cmd_enc(struct acipher *state, uint32_t pt,
53 			  TEE_Param params[TEE_NUM_PARAMS])
54 {
55 	TEE_Result res;
56 	const void *inbuf;
57 	uint32_t inbuf_len;
58 	void *outbuf;
59 	uint32_t outbuf_len;
60 	TEE_OperationHandle op;
61 	TEE_ObjectInfo key_info;
62 	const uint32_t alg = TEE_ALG_RSAES_PKCS1_V1_5;
63 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
64 						TEE_PARAM_TYPE_MEMREF_OUTPUT,
65 						TEE_PARAM_TYPE_NONE,
66 						TEE_PARAM_TYPE_NONE);
67 
68 	if (pt != exp_pt)
69 		return TEE_ERROR_BAD_PARAMETERS;
70 	if (!state->key)
71 		return TEE_ERROR_BAD_STATE;
72 
73 	res = TEE_GetObjectInfo1(state->key, &key_info);
74 	if (res) {
75 		EMSG("TEE_GetObjectInfo1: %#" PRIx32, res);
76 		return res;
77 	}
78 
79 	inbuf = params[0].memref.buffer;
80 	inbuf_len = params[0].memref.size;
81 	outbuf = params[1].memref.buffer;
82 	outbuf_len = params[1].memref.size;
83 
84 	res = TEE_AllocateOperation(&op, alg, TEE_MODE_ENCRYPT,
85 				    key_info.keySize);
86 	if (res) {
87 		EMSG("TEE_AllocateOperation(TEE_MODE_ENCRYPT, %#" PRIx32 ", %" PRId32 "): %#" PRIx32, alg, key_info.keySize, res);
88 		return res;
89 	}
90 
91 	res = TEE_SetOperationKey(op, state->key);
92 	if (res) {
93 		EMSG("TEE_SetOperationKey: %#" PRIx32, res);
94 		goto out;
95 	}
96 
97 	res = TEE_AsymmetricEncrypt(op, NULL, 0, inbuf, inbuf_len, outbuf,
98 				    &outbuf_len);
99 	if (res) {
100 		EMSG("TEE_AsymmetricEncrypt(%" PRId32 ", %" PRId32 "): %#" PRIx32, inbuf_len, params[1].memref.size, res);
101 	}
102 	params[1].memref.size = outbuf_len;
103 
104 out:
105 	TEE_FreeOperation(op);
106 	return res;
107 
108 }
109 
TA_CreateEntryPoint(void)110 TEE_Result TA_CreateEntryPoint(void)
111 {
112 	/* Nothing to do */
113 	return TEE_SUCCESS;
114 }
115 
TA_DestroyEntryPoint(void)116 void TA_DestroyEntryPoint(void)
117 {
118 	/* Nothing to do */
119 }
120 
TA_OpenSessionEntryPoint(uint32_t __unused param_types,TEE_Param __unused params[4],void ** session)121 TEE_Result TA_OpenSessionEntryPoint(uint32_t __unused param_types,
122 					TEE_Param __unused params[4],
123 					void **session)
124 {
125 	struct acipher *state;
126 
127 	/*
128 	 * Allocate and init state for the session.
129 	 */
130 	state = TEE_Malloc(sizeof(*state), 0);
131 	if (!state)
132 		return TEE_ERROR_OUT_OF_MEMORY;
133 
134 	state->key = TEE_HANDLE_NULL;
135 
136 	*session = state;
137 
138 	return TEE_SUCCESS;
139 }
140 
TA_CloseSessionEntryPoint(void * session)141 void TA_CloseSessionEntryPoint(void *session)
142 {
143 	struct acipher *state = session;
144 
145 	TEE_FreeTransientObject(state->key);
146 	TEE_Free(state);
147 }
148 
TA_InvokeCommandEntryPoint(void * session,uint32_t cmd,uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])149 TEE_Result TA_InvokeCommandEntryPoint(void *session, uint32_t cmd,
150 				      uint32_t param_types,
151 				      TEE_Param params[TEE_NUM_PARAMS])
152 {
153 	switch (cmd) {
154 	case TA_ACIPHER_CMD_GEN_KEY:
155 		return cmd_gen_key(session, param_types, params);
156 	case TA_ACIPHER_CMD_ENCRYPT:
157 		return cmd_enc(session, param_types, params);
158 	default:
159 		EMSG("Command ID %#" PRIx32 " is not supported", cmd);
160 		return TEE_ERROR_NOT_SUPPORTED;
161 	}
162 }
163