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