xref: /optee_os/lib/libutee/tee_api_property.c (revision b01047730e77127c23a36591643eeb8bb0487d68)
1*b0104773SPascal Brand /*
2*b0104773SPascal Brand  * Copyright (c) 2014, STMicroelectronics International N.V.
3*b0104773SPascal Brand  * All rights reserved.
4*b0104773SPascal Brand  *
5*b0104773SPascal Brand  * Redistribution and use in source and binary forms, with or without
6*b0104773SPascal Brand  * modification, are permitted provided that the following conditions are met:
7*b0104773SPascal Brand  *
8*b0104773SPascal Brand  * 1. Redistributions of source code must retain the above copyright notice,
9*b0104773SPascal Brand  * this list of conditions and the following disclaimer.
10*b0104773SPascal Brand  *
11*b0104773SPascal Brand  * 2. Redistributions in binary form must reproduce the above copyright notice,
12*b0104773SPascal Brand  * this list of conditions and the following disclaimer in the documentation
13*b0104773SPascal Brand  * and/or other materials provided with the distribution.
14*b0104773SPascal Brand  *
15*b0104773SPascal Brand  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16*b0104773SPascal Brand  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17*b0104773SPascal Brand  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18*b0104773SPascal Brand  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19*b0104773SPascal Brand  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20*b0104773SPascal Brand  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21*b0104773SPascal Brand  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22*b0104773SPascal Brand  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23*b0104773SPascal Brand  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24*b0104773SPascal Brand  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25*b0104773SPascal Brand  * POSSIBILITY OF SUCH DAMAGE.
26*b0104773SPascal Brand  */
27*b0104773SPascal Brand #include <tee_api.h>
28*b0104773SPascal Brand 
29*b0104773SPascal Brand #include <stdlib.h>
30*b0104773SPascal Brand #include <string.h>
31*b0104773SPascal Brand #include <stdio.h>
32*b0104773SPascal Brand #include <tee_api_defines.h>
33*b0104773SPascal Brand #include <tee_api_types.h>
34*b0104773SPascal Brand #include <user_ta_header.h>
35*b0104773SPascal Brand #include <tee_internal_api_extensions.h>
36*b0104773SPascal Brand 
37*b0104773SPascal Brand #include <utee_syscalls.h>
38*b0104773SPascal Brand 
39*b0104773SPascal Brand #include "string_ext.h"
40*b0104773SPascal Brand #include "base64.h"
41*b0104773SPascal Brand 
42*b0104773SPascal Brand #define PROP_STR_MAX    80
43*b0104773SPascal Brand 
44*b0104773SPascal Brand #define PROP_ENUMERATOR_NOT_STARTED 0xffffffff
45*b0104773SPascal Brand 
46*b0104773SPascal Brand struct prop_enumerator {
47*b0104773SPascal Brand 	uint32_t idx;
48*b0104773SPascal Brand 	TEE_PropSetHandle prop_set;
49*b0104773SPascal Brand };
50*b0104773SPascal Brand 
51*b0104773SPascal Brand struct prop_value {
52*b0104773SPascal Brand 	enum user_ta_prop_type type;
53*b0104773SPascal Brand 	union {
54*b0104773SPascal Brand 		bool bool_val;
55*b0104773SPascal Brand 		uint32_t int_val;
56*b0104773SPascal Brand 		TEE_UUID uuid_val;
57*b0104773SPascal Brand 		TEE_Identity identity_val;
58*b0104773SPascal Brand 		char str_val[PROP_STR_MAX];
59*b0104773SPascal Brand 	} u;
60*b0104773SPascal Brand };
61*b0104773SPascal Brand 
62*b0104773SPascal Brand typedef TEE_Result(*ta_propget_func_t) (struct prop_value *pv);
63*b0104773SPascal Brand 
64*b0104773SPascal Brand struct prop_set {
65*b0104773SPascal Brand 	const char *str;
66*b0104773SPascal Brand 	ta_propget_func_t get;
67*b0104773SPascal Brand };
68*b0104773SPascal Brand 
69*b0104773SPascal Brand static TEE_Result propget_gpd_ta_app_id(struct prop_value *pv)
70*b0104773SPascal Brand {
71*b0104773SPascal Brand 	pv->type = USER_TA_PROP_TYPE_UUID;
72*b0104773SPascal Brand 	return utee_get_property(UTEE_PROP_TA_APP_ID, &pv->u.uuid_val,
73*b0104773SPascal Brand 				 sizeof(pv->u.uuid_val));
74*b0104773SPascal Brand }
75*b0104773SPascal Brand 
76*b0104773SPascal Brand static TEE_Result propget_gpd_client_identity(struct prop_value *pv)
77*b0104773SPascal Brand {
78*b0104773SPascal Brand 	pv->type = USER_TA_PROP_TYPE_IDENTITY;
79*b0104773SPascal Brand 	return utee_get_property(UTEE_PROP_CLIENT_ID, &pv->u.identity_val,
80*b0104773SPascal Brand 				 sizeof(pv->u.identity_val));
81*b0104773SPascal Brand }
82*b0104773SPascal Brand 
83*b0104773SPascal Brand static TEE_Result propget_gpd_tee_api_version(struct prop_value *pv)
84*b0104773SPascal Brand {
85*b0104773SPascal Brand 	pv->type = USER_TA_PROP_TYPE_STRING;
86*b0104773SPascal Brand 	return utee_get_property(UTEE_PROP_TEE_API_VERSION, &pv->u.str_val,
87*b0104773SPascal Brand 				 sizeof(pv->u.str_val));
88*b0104773SPascal Brand }
89*b0104773SPascal Brand 
90*b0104773SPascal Brand static TEE_Result propget_gpd_tee_description(struct prop_value *pv)
91*b0104773SPascal Brand {
92*b0104773SPascal Brand 	pv->type = USER_TA_PROP_TYPE_STRING;
93*b0104773SPascal Brand 	return utee_get_property(UTEE_PROP_TEE_DESCR, &pv->u.str_val,
94*b0104773SPascal Brand 				 sizeof(pv->u.str_val));
95*b0104773SPascal Brand }
96*b0104773SPascal Brand 
97*b0104773SPascal Brand static TEE_Result propget_gpd_tee_device_id(struct prop_value *pv)
98*b0104773SPascal Brand {
99*b0104773SPascal Brand 	pv->type = USER_TA_PROP_TYPE_UUID;
100*b0104773SPascal Brand 	return utee_get_property(UTEE_PROP_TEE_DEV_ID, &pv->u.uuid_val,
101*b0104773SPascal Brand 				 sizeof(pv->u.uuid_val));
102*b0104773SPascal Brand }
103*b0104773SPascal Brand 
104*b0104773SPascal Brand static TEE_Result propget_gpd_tee_sys_time_protection_level(struct prop_value
105*b0104773SPascal Brand 							    *pv)
106*b0104773SPascal Brand {
107*b0104773SPascal Brand 	pv->type = USER_TA_PROP_TYPE_U32;
108*b0104773SPascal Brand 	return utee_get_property(UTEE_PROP_TEE_SYS_TIME_PROT_LEVEL,
109*b0104773SPascal Brand 				 &pv->u.int_val, sizeof(pv->u.int_val));
110*b0104773SPascal Brand }
111*b0104773SPascal Brand 
112*b0104773SPascal Brand static TEE_Result propget_gpd_tee_ta_time_protection_level(struct prop_value
113*b0104773SPascal Brand 							   *pv)
114*b0104773SPascal Brand {
115*b0104773SPascal Brand 	pv->type = USER_TA_PROP_TYPE_U32;
116*b0104773SPascal Brand 	return utee_get_property(UTEE_PROP_TEE_TA_TIME_PROT_LEVEL,
117*b0104773SPascal Brand 				 &pv->u.int_val, sizeof(pv->u.int_val));
118*b0104773SPascal Brand }
119*b0104773SPascal Brand 
120*b0104773SPascal Brand static TEE_Result propget_gpd_tee_arith_max_big_int_size(struct prop_value *pv)
121*b0104773SPascal Brand {
122*b0104773SPascal Brand 	pv->type = USER_TA_PROP_TYPE_U32;
123*b0104773SPascal Brand 	return utee_get_property(UTEE_PROP_TEE_ARITH_MAX_BIG_INT_SIZE,
124*b0104773SPascal Brand 				 &pv->u.int_val, sizeof(pv->u.int_val));
125*b0104773SPascal Brand }
126*b0104773SPascal Brand 
127*b0104773SPascal Brand static const struct prop_set propset_current_ta[] = {
128*b0104773SPascal Brand 	{"gpd.ta.appID", propget_gpd_ta_app_id},
129*b0104773SPascal Brand };
130*b0104773SPascal Brand 
131*b0104773SPascal Brand static const size_t propset_current_ta_len =
132*b0104773SPascal Brand 	sizeof(propset_current_ta) / sizeof(propset_current_ta[0]);
133*b0104773SPascal Brand 
134*b0104773SPascal Brand static const struct prop_set propset_current_client[] = {
135*b0104773SPascal Brand 	{"gpd.client.identity", propget_gpd_client_identity},
136*b0104773SPascal Brand };
137*b0104773SPascal Brand 
138*b0104773SPascal Brand static const size_t propset_current_client_len =
139*b0104773SPascal Brand 	sizeof(propset_current_client) / sizeof(propset_current_client[0]);
140*b0104773SPascal Brand 
141*b0104773SPascal Brand static const struct prop_set propset_implementation[] = {
142*b0104773SPascal Brand 	{"gpd.tee.apiversion", propget_gpd_tee_api_version},
143*b0104773SPascal Brand 	{"gpd.tee.description", propget_gpd_tee_description},
144*b0104773SPascal Brand 	{"gpd.tee.deviceID", propget_gpd_tee_device_id},
145*b0104773SPascal Brand 	{"gpd.tee.systemTime.protectionLevel",
146*b0104773SPascal Brand 	 propget_gpd_tee_sys_time_protection_level},
147*b0104773SPascal Brand 	{"gpd.tee.TAPersistentTime.protectionLevel",
148*b0104773SPascal Brand 	 propget_gpd_tee_ta_time_protection_level},
149*b0104773SPascal Brand 	{"gpd.tee.arith.maxBigIntSize", propget_gpd_tee_arith_max_big_int_size},
150*b0104773SPascal Brand };
151*b0104773SPascal Brand 
152*b0104773SPascal Brand static const size_t propset_implementation_len =
153*b0104773SPascal Brand 	sizeof(propset_implementation) / sizeof(propset_implementation[0]);
154*b0104773SPascal Brand 
155*b0104773SPascal Brand static TEE_Result propset_get(TEE_PropSetHandle h, const struct prop_set **ps,
156*b0104773SPascal Brand 			      size_t *ps_len,
157*b0104773SPascal Brand 			      const struct user_ta_property **eps,
158*b0104773SPascal Brand 			      size_t *eps_len)
159*b0104773SPascal Brand {
160*b0104773SPascal Brand 	if (h == TEE_PROPSET_CURRENT_TA) {
161*b0104773SPascal Brand 		*ps = propset_current_ta;
162*b0104773SPascal Brand 		*ps_len = propset_current_ta_len;
163*b0104773SPascal Brand 		*eps = ta_props;
164*b0104773SPascal Brand 		*eps_len = ta_num_props;
165*b0104773SPascal Brand 	} else if (h == TEE_PROPSET_CURRENT_CLIENT) {
166*b0104773SPascal Brand 		*ps = propset_current_client;
167*b0104773SPascal Brand 		*ps_len = propset_current_client_len;
168*b0104773SPascal Brand 		*eps = NULL;
169*b0104773SPascal Brand 		*eps_len = 0;
170*b0104773SPascal Brand 	} else if (h == TEE_PROPSET_TEE_IMPLEMENTATION) {
171*b0104773SPascal Brand 		*ps = propset_implementation;
172*b0104773SPascal Brand 		*ps_len = propset_implementation_len;
173*b0104773SPascal Brand 		*eps = NULL;
174*b0104773SPascal Brand 		*eps_len = 0;
175*b0104773SPascal Brand 	} else {
176*b0104773SPascal Brand 		return TEE_ERROR_ITEM_NOT_FOUND;
177*b0104773SPascal Brand 	}
178*b0104773SPascal Brand 
179*b0104773SPascal Brand 	return TEE_SUCCESS;
180*b0104773SPascal Brand }
181*b0104773SPascal Brand 
182*b0104773SPascal Brand static TEE_Result propget_get_ext_prop(const struct user_ta_property *ep,
183*b0104773SPascal Brand 				       struct prop_value *pv)
184*b0104773SPascal Brand {
185*b0104773SPascal Brand 	size_t l;
186*b0104773SPascal Brand 
187*b0104773SPascal Brand 	pv->type = ep->type;
188*b0104773SPascal Brand 	switch (ep->type) {
189*b0104773SPascal Brand 	case USER_TA_PROP_TYPE_BOOL:
190*b0104773SPascal Brand 		l = sizeof(bool);
191*b0104773SPascal Brand 		break;
192*b0104773SPascal Brand 	case USER_TA_PROP_TYPE_U32:
193*b0104773SPascal Brand 		l = sizeof(uint32_t);
194*b0104773SPascal Brand 		break;
195*b0104773SPascal Brand 	case USER_TA_PROP_TYPE_UUID:
196*b0104773SPascal Brand 		l = sizeof(TEE_UUID);
197*b0104773SPascal Brand 		break;
198*b0104773SPascal Brand 	case USER_TA_PROP_TYPE_IDENTITY:
199*b0104773SPascal Brand 		l = sizeof(TEE_Identity);
200*b0104773SPascal Brand 		break;
201*b0104773SPascal Brand 	case USER_TA_PROP_TYPE_STRING:
202*b0104773SPascal Brand 	case USER_TA_PROP_TYPE_BINARY_BLOCK:
203*b0104773SPascal Brand 		/* Handle too large strings by truncating them */
204*b0104773SPascal Brand 		strlcpy(pv->u.str_val, ep->value, sizeof(pv->u.str_val));
205*b0104773SPascal Brand 		return TEE_SUCCESS;
206*b0104773SPascal Brand 	default:
207*b0104773SPascal Brand 		return TEE_ERROR_GENERIC;
208*b0104773SPascal Brand 	}
209*b0104773SPascal Brand 	memcpy(&pv->u, ep->value, l);
210*b0104773SPascal Brand 	return TEE_SUCCESS;
211*b0104773SPascal Brand }
212*b0104773SPascal Brand 
213*b0104773SPascal Brand static TEE_Result propget_get_property(TEE_PropSetHandle h, char *name,
214*b0104773SPascal Brand 				       struct prop_value *pv)
215*b0104773SPascal Brand {
216*b0104773SPascal Brand 	TEE_Result res;
217*b0104773SPascal Brand 	const struct prop_set *ps;
218*b0104773SPascal Brand 	size_t ps_len;
219*b0104773SPascal Brand 	const struct user_ta_property *eps;
220*b0104773SPascal Brand 	size_t eps_len;
221*b0104773SPascal Brand 
222*b0104773SPascal Brand 	if (h == TEE_PROPSET_CURRENT_TA || h == TEE_PROPSET_CURRENT_CLIENT ||
223*b0104773SPascal Brand 	    h == TEE_PROPSET_TEE_IMPLEMENTATION) {
224*b0104773SPascal Brand 		size_t n;
225*b0104773SPascal Brand 
226*b0104773SPascal Brand 		res = propset_get(h, &ps, &ps_len, &eps, &eps_len);
227*b0104773SPascal Brand 		if (res != TEE_SUCCESS)
228*b0104773SPascal Brand 			return res;
229*b0104773SPascal Brand 
230*b0104773SPascal Brand 		for (n = 0; n < ps_len; n++) {
231*b0104773SPascal Brand 			if (strcmp(name, ps[n].str) == 0)
232*b0104773SPascal Brand 				return ps[n].get(pv);
233*b0104773SPascal Brand 		}
234*b0104773SPascal Brand 		for (n = 0; n < eps_len; n++) {
235*b0104773SPascal Brand 			if (strcmp(name, eps[n].name) == 0)
236*b0104773SPascal Brand 				return propget_get_ext_prop(eps + n, pv);
237*b0104773SPascal Brand 		}
238*b0104773SPascal Brand 		return TEE_ERROR_ITEM_NOT_FOUND;
239*b0104773SPascal Brand 	} else {
240*b0104773SPascal Brand 		struct prop_enumerator *pe = (struct prop_enumerator *)h;
241*b0104773SPascal Brand 		uint32_t idx = pe->idx;
242*b0104773SPascal Brand 
243*b0104773SPascal Brand 		if (idx == PROP_ENUMERATOR_NOT_STARTED)
244*b0104773SPascal Brand 			return TEE_ERROR_ITEM_NOT_FOUND;
245*b0104773SPascal Brand 
246*b0104773SPascal Brand 		res = propset_get(pe->prop_set, &ps, &ps_len, &eps, &eps_len);
247*b0104773SPascal Brand 		if (res != TEE_SUCCESS)
248*b0104773SPascal Brand 			return res;
249*b0104773SPascal Brand 
250*b0104773SPascal Brand 		if (idx < ps_len)
251*b0104773SPascal Brand 			return ps[idx].get(pv);
252*b0104773SPascal Brand 
253*b0104773SPascal Brand 		idx -= ps_len;
254*b0104773SPascal Brand 		if (idx < eps_len)
255*b0104773SPascal Brand 			return propget_get_ext_prop(eps + idx, pv);
256*b0104773SPascal Brand 
257*b0104773SPascal Brand 		return TEE_ERROR_BAD_PARAMETERS;
258*b0104773SPascal Brand 	}
259*b0104773SPascal Brand }
260*b0104773SPascal Brand 
261*b0104773SPascal Brand TEE_Result TEE_GetPropertyAsString(TEE_PropSetHandle propsetOrEnumerator,
262*b0104773SPascal Brand 				   char *name, char *valueBuffer,
263*b0104773SPascal Brand 				   size_t *valueBufferLen)
264*b0104773SPascal Brand {
265*b0104773SPascal Brand 	TEE_Result res;
266*b0104773SPascal Brand 	struct prop_value pv;
267*b0104773SPascal Brand 	size_t l;
268*b0104773SPascal Brand 	size_t bufferlen;
269*b0104773SPascal Brand 
270*b0104773SPascal Brand 	if (valueBuffer == NULL || valueBufferLen == NULL)
271*b0104773SPascal Brand 		return TEE_ERROR_BAD_PARAMETERS;
272*b0104773SPascal Brand 
273*b0104773SPascal Brand 	bufferlen = *valueBufferLen;
274*b0104773SPascal Brand 
275*b0104773SPascal Brand 	res = propget_get_property(propsetOrEnumerator, name, &pv);
276*b0104773SPascal Brand 	if (res != TEE_SUCCESS)
277*b0104773SPascal Brand 		return res;
278*b0104773SPascal Brand 
279*b0104773SPascal Brand 	switch (pv.type) {
280*b0104773SPascal Brand 	case USER_TA_PROP_TYPE_BOOL:
281*b0104773SPascal Brand 		l = strlcpy(valueBuffer, pv.u.bool_val ? "true" : "false",
282*b0104773SPascal Brand 			    bufferlen);
283*b0104773SPascal Brand 		break;
284*b0104773SPascal Brand 
285*b0104773SPascal Brand 	case USER_TA_PROP_TYPE_U32:
286*b0104773SPascal Brand 		l = snprintf(valueBuffer, bufferlen, "%u",
287*b0104773SPascal Brand 			     (unsigned int)pv.u.int_val);
288*b0104773SPascal Brand 		break;
289*b0104773SPascal Brand 
290*b0104773SPascal Brand 	case USER_TA_PROP_TYPE_UUID:
291*b0104773SPascal Brand 		l = snprintf(valueBuffer, bufferlen,
292*b0104773SPascal Brand 			     "%08x-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x",
293*b0104773SPascal Brand 			     (unsigned int)pv.u.uuid_val.timeLow,
294*b0104773SPascal Brand 			     pv.u.uuid_val.timeMid,
295*b0104773SPascal Brand 			     pv.u.uuid_val.timeHiAndVersion,
296*b0104773SPascal Brand 			     pv.u.uuid_val.clockSeqAndNode[0],
297*b0104773SPascal Brand 			     pv.u.uuid_val.clockSeqAndNode[1],
298*b0104773SPascal Brand 			     pv.u.uuid_val.clockSeqAndNode[2],
299*b0104773SPascal Brand 			     pv.u.uuid_val.clockSeqAndNode[3],
300*b0104773SPascal Brand 			     pv.u.uuid_val.clockSeqAndNode[4],
301*b0104773SPascal Brand 			     pv.u.uuid_val.clockSeqAndNode[5],
302*b0104773SPascal Brand 			     pv.u.uuid_val.clockSeqAndNode[6],
303*b0104773SPascal Brand 			     pv.u.uuid_val.clockSeqAndNode[7]);
304*b0104773SPascal Brand 		break;
305*b0104773SPascal Brand 
306*b0104773SPascal Brand 	case USER_TA_PROP_TYPE_IDENTITY:
307*b0104773SPascal Brand 		l = snprintf(valueBuffer, bufferlen,
308*b0104773SPascal Brand 			     "%u:%08x-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x",
309*b0104773SPascal Brand 			     (unsigned int)pv.u.identity_val.login,
310*b0104773SPascal Brand 			     (unsigned int)pv.u.identity_val.uuid.timeLow,
311*b0104773SPascal Brand 			     pv.u.identity_val.uuid.timeMid,
312*b0104773SPascal Brand 			     pv.u.identity_val.uuid.timeHiAndVersion,
313*b0104773SPascal Brand 			     pv.u.identity_val.uuid.clockSeqAndNode[0],
314*b0104773SPascal Brand 			     pv.u.identity_val.uuid.clockSeqAndNode[1],
315*b0104773SPascal Brand 			     pv.u.identity_val.uuid.clockSeqAndNode[2],
316*b0104773SPascal Brand 			     pv.u.identity_val.uuid.clockSeqAndNode[3],
317*b0104773SPascal Brand 			     pv.u.identity_val.uuid.clockSeqAndNode[4],
318*b0104773SPascal Brand 			     pv.u.identity_val.uuid.clockSeqAndNode[5],
319*b0104773SPascal Brand 			     pv.u.identity_val.uuid.clockSeqAndNode[6],
320*b0104773SPascal Brand 			     pv.u.identity_val.uuid.clockSeqAndNode[7]);
321*b0104773SPascal Brand 		break;
322*b0104773SPascal Brand 
323*b0104773SPascal Brand 	case USER_TA_PROP_TYPE_STRING:
324*b0104773SPascal Brand 	case USER_TA_PROP_TYPE_BINARY_BLOCK:
325*b0104773SPascal Brand 		l = strlcpy(valueBuffer, pv.u.str_val, bufferlen);
326*b0104773SPascal Brand 		break;
327*b0104773SPascal Brand 
328*b0104773SPascal Brand 	default:
329*b0104773SPascal Brand 		return TEE_ERROR_BAD_FORMAT;
330*b0104773SPascal Brand 	}
331*b0104773SPascal Brand 
332*b0104773SPascal Brand 	/* The size "must account for the zero terminator" */
333*b0104773SPascal Brand 	*valueBufferLen = l + 1;
334*b0104773SPascal Brand 
335*b0104773SPascal Brand 	if (l >= bufferlen)
336*b0104773SPascal Brand 		return TEE_ERROR_SHORT_BUFFER;
337*b0104773SPascal Brand 
338*b0104773SPascal Brand 	return TEE_SUCCESS;
339*b0104773SPascal Brand }
340*b0104773SPascal Brand 
341*b0104773SPascal Brand TEE_Result TEE_GetPropertyAsBool(TEE_PropSetHandle propsetOrEnumerator,
342*b0104773SPascal Brand 				 char *name, bool *value)
343*b0104773SPascal Brand {
344*b0104773SPascal Brand 	TEE_Result res;
345*b0104773SPascal Brand 	struct prop_value pv;
346*b0104773SPascal Brand 
347*b0104773SPascal Brand 	if (value == NULL)
348*b0104773SPascal Brand 		return TEE_ERROR_BAD_PARAMETERS;
349*b0104773SPascal Brand 
350*b0104773SPascal Brand 	res = propget_get_property(propsetOrEnumerator, name, &pv);
351*b0104773SPascal Brand 	if (res != TEE_SUCCESS)
352*b0104773SPascal Brand 		return res;
353*b0104773SPascal Brand 
354*b0104773SPascal Brand 	if (pv.type != USER_TA_PROP_TYPE_BOOL)
355*b0104773SPascal Brand 		return TEE_ERROR_BAD_FORMAT;
356*b0104773SPascal Brand 
357*b0104773SPascal Brand 	*value = pv.u.bool_val;
358*b0104773SPascal Brand 	return TEE_SUCCESS;
359*b0104773SPascal Brand }
360*b0104773SPascal Brand 
361*b0104773SPascal Brand TEE_Result TEE_GetPropertyAsU32(TEE_PropSetHandle propsetOrEnumerator,
362*b0104773SPascal Brand 				char *name, uint32_t *value)
363*b0104773SPascal Brand {
364*b0104773SPascal Brand 	TEE_Result res;
365*b0104773SPascal Brand 	struct prop_value pv;
366*b0104773SPascal Brand 
367*b0104773SPascal Brand 	if (value == NULL)
368*b0104773SPascal Brand 		return TEE_ERROR_BAD_PARAMETERS;
369*b0104773SPascal Brand 
370*b0104773SPascal Brand 	res = propget_get_property(propsetOrEnumerator, name, &pv);
371*b0104773SPascal Brand 	if (res != TEE_SUCCESS)
372*b0104773SPascal Brand 		return res;
373*b0104773SPascal Brand 
374*b0104773SPascal Brand 	if (pv.type != USER_TA_PROP_TYPE_U32)
375*b0104773SPascal Brand 		return TEE_ERROR_BAD_FORMAT;
376*b0104773SPascal Brand 
377*b0104773SPascal Brand 	*value = pv.u.int_val;
378*b0104773SPascal Brand 	return TEE_SUCCESS;
379*b0104773SPascal Brand }
380*b0104773SPascal Brand 
381*b0104773SPascal Brand TEE_Result TEE_GetPropertyAsBinaryBlock(TEE_PropSetHandle propsetOrEnumerator,
382*b0104773SPascal Brand 					char *name, void *valueBuffer,
383*b0104773SPascal Brand 					size_t *valueBufferLen)
384*b0104773SPascal Brand {
385*b0104773SPascal Brand 	TEE_Result res;
386*b0104773SPascal Brand 	struct prop_value pv;
387*b0104773SPascal Brand 	void *val;
388*b0104773SPascal Brand 	int val_len;
389*b0104773SPascal Brand 
390*b0104773SPascal Brand 	if (valueBuffer == NULL || valueBufferLen == NULL)
391*b0104773SPascal Brand 		return TEE_ERROR_BAD_PARAMETERS;
392*b0104773SPascal Brand 
393*b0104773SPascal Brand 	res = propget_get_property(propsetOrEnumerator, name, &pv);
394*b0104773SPascal Brand 	if (res != TEE_SUCCESS)
395*b0104773SPascal Brand 		return res;
396*b0104773SPascal Brand 
397*b0104773SPascal Brand 	if (pv.type != USER_TA_PROP_TYPE_BINARY_BLOCK)
398*b0104773SPascal Brand 		return TEE_ERROR_BAD_FORMAT;
399*b0104773SPascal Brand 
400*b0104773SPascal Brand 	val = pv.u.str_val;
401*b0104773SPascal Brand 	val_len = strlen(val);
402*b0104773SPascal Brand 	if (!base64_dec(val, val_len, valueBuffer, valueBufferLen))
403*b0104773SPascal Brand 		return TEE_ERROR_SHORT_BUFFER;
404*b0104773SPascal Brand 	return TEE_SUCCESS;
405*b0104773SPascal Brand }
406*b0104773SPascal Brand 
407*b0104773SPascal Brand TEE_Result TEE_GetPropertyAsUUID(TEE_PropSetHandle propsetOrEnumerator,
408*b0104773SPascal Brand 				 char *name, TEE_UUID *value)
409*b0104773SPascal Brand {
410*b0104773SPascal Brand 	TEE_Result res;
411*b0104773SPascal Brand 	struct prop_value pv;
412*b0104773SPascal Brand 
413*b0104773SPascal Brand 	if (value == NULL)
414*b0104773SPascal Brand 		return TEE_ERROR_BAD_PARAMETERS;
415*b0104773SPascal Brand 
416*b0104773SPascal Brand 	res = propget_get_property(propsetOrEnumerator, name, &pv);
417*b0104773SPascal Brand 	if (res != TEE_SUCCESS)
418*b0104773SPascal Brand 		return res;
419*b0104773SPascal Brand 
420*b0104773SPascal Brand 	if (pv.type != USER_TA_PROP_TYPE_UUID)
421*b0104773SPascal Brand 		return TEE_ERROR_BAD_FORMAT;
422*b0104773SPascal Brand 
423*b0104773SPascal Brand 	*value = pv.u.uuid_val;	/* struct copy */
424*b0104773SPascal Brand 	return TEE_SUCCESS;
425*b0104773SPascal Brand }
426*b0104773SPascal Brand 
427*b0104773SPascal Brand TEE_Result TEE_GetPropertyAsIdentity(TEE_PropSetHandle propsetOrEnumerator,
428*b0104773SPascal Brand 				     char *name, TEE_Identity *value)
429*b0104773SPascal Brand {
430*b0104773SPascal Brand 	TEE_Result res;
431*b0104773SPascal Brand 	struct prop_value pv;
432*b0104773SPascal Brand 
433*b0104773SPascal Brand 	if (value == NULL)
434*b0104773SPascal Brand 		return TEE_ERROR_BAD_PARAMETERS;
435*b0104773SPascal Brand 
436*b0104773SPascal Brand 	res = propget_get_property(propsetOrEnumerator, name, &pv);
437*b0104773SPascal Brand 	if (res != TEE_SUCCESS)
438*b0104773SPascal Brand 		return res;
439*b0104773SPascal Brand 
440*b0104773SPascal Brand 	if (pv.type != USER_TA_PROP_TYPE_IDENTITY)
441*b0104773SPascal Brand 		return TEE_ERROR_BAD_FORMAT;
442*b0104773SPascal Brand 
443*b0104773SPascal Brand 	*value = pv.u.identity_val;	/* struct copy */
444*b0104773SPascal Brand 	return TEE_SUCCESS;
445*b0104773SPascal Brand }
446*b0104773SPascal Brand 
447*b0104773SPascal Brand TEE_Result TEE_AllocatePropertyEnumerator(TEE_PropSetHandle *enumerator)
448*b0104773SPascal Brand {
449*b0104773SPascal Brand 	struct prop_enumerator *pe;
450*b0104773SPascal Brand 
451*b0104773SPascal Brand 	if (enumerator == NULL)
452*b0104773SPascal Brand 		return TEE_ERROR_BAD_PARAMETERS;
453*b0104773SPascal Brand 
454*b0104773SPascal Brand 	pe = TEE_Malloc(sizeof(struct prop_enumerator),
455*b0104773SPascal Brand 			TEE_USER_MEM_HINT_NO_FILL_ZERO);
456*b0104773SPascal Brand 	if (pe == NULL)
457*b0104773SPascal Brand 		return TEE_ERROR_OUT_OF_MEMORY;
458*b0104773SPascal Brand 
459*b0104773SPascal Brand 	*enumerator = (TEE_PropSetHandle) pe;
460*b0104773SPascal Brand 	TEE_ResetPropertyEnumerator(*enumerator);
461*b0104773SPascal Brand 	return TEE_SUCCESS;
462*b0104773SPascal Brand }
463*b0104773SPascal Brand 
464*b0104773SPascal Brand void TEE_ResetPropertyEnumerator(TEE_PropSetHandle enumerator)
465*b0104773SPascal Brand {
466*b0104773SPascal Brand 	struct prop_enumerator *pe = (struct prop_enumerator *)enumerator;
467*b0104773SPascal Brand 
468*b0104773SPascal Brand 	pe->idx = PROP_ENUMERATOR_NOT_STARTED;
469*b0104773SPascal Brand }
470*b0104773SPascal Brand 
471*b0104773SPascal Brand void TEE_FreePropertyEnumerator(TEE_PropSetHandle enumerator)
472*b0104773SPascal Brand {
473*b0104773SPascal Brand 	struct prop_enumerator *pe = (struct prop_enumerator *)enumerator;
474*b0104773SPascal Brand 
475*b0104773SPascal Brand 	TEE_Free(pe);
476*b0104773SPascal Brand }
477*b0104773SPascal Brand 
478*b0104773SPascal Brand void TEE_StartPropertyEnumerator(TEE_PropSetHandle enumerator,
479*b0104773SPascal Brand 				 TEE_PropSetHandle propSet)
480*b0104773SPascal Brand {
481*b0104773SPascal Brand 	struct prop_enumerator *pe = (struct prop_enumerator *)enumerator;
482*b0104773SPascal Brand 
483*b0104773SPascal Brand 	if (pe == NULL)
484*b0104773SPascal Brand 		return;
485*b0104773SPascal Brand 
486*b0104773SPascal Brand 	pe->idx = 0;
487*b0104773SPascal Brand 	pe->prop_set = propSet;
488*b0104773SPascal Brand }
489*b0104773SPascal Brand 
490*b0104773SPascal Brand TEE_Result TEE_GetPropertyName(TEE_PropSetHandle enumerator,
491*b0104773SPascal Brand 			       void *nameBuffer, size_t *nameBufferLen)
492*b0104773SPascal Brand {
493*b0104773SPascal Brand 	TEE_Result res;
494*b0104773SPascal Brand 	struct prop_enumerator *pe = (struct prop_enumerator *)enumerator;
495*b0104773SPascal Brand 	const struct prop_set *ps;
496*b0104773SPascal Brand 	size_t ps_len;
497*b0104773SPascal Brand 	const struct user_ta_property *eps;
498*b0104773SPascal Brand 	size_t eps_len;
499*b0104773SPascal Brand 	size_t l;
500*b0104773SPascal Brand 	const char *str;
501*b0104773SPascal Brand 	size_t bufferlen;
502*b0104773SPascal Brand 
503*b0104773SPascal Brand 	if (pe == NULL || nameBuffer == NULL || nameBufferLen == NULL)
504*b0104773SPascal Brand 		return TEE_ERROR_BAD_PARAMETERS;
505*b0104773SPascal Brand 
506*b0104773SPascal Brand 	bufferlen = *nameBufferLen;
507*b0104773SPascal Brand 	res = propset_get(pe->prop_set, &ps, &ps_len, &eps, &eps_len);
508*b0104773SPascal Brand 	if (res != TEE_SUCCESS)
509*b0104773SPascal Brand 		return res;
510*b0104773SPascal Brand 
511*b0104773SPascal Brand 	if (pe->idx < ps_len)
512*b0104773SPascal Brand 		str = ps[pe->idx].str;
513*b0104773SPascal Brand 	else if ((pe->idx - ps_len) < eps_len)
514*b0104773SPascal Brand 		str = ta_props[pe->idx - ps_len].name;
515*b0104773SPascal Brand 	else
516*b0104773SPascal Brand 		return TEE_ERROR_ITEM_NOT_FOUND;
517*b0104773SPascal Brand 
518*b0104773SPascal Brand 	l = strlcpy(nameBuffer, str, bufferlen);
519*b0104773SPascal Brand 
520*b0104773SPascal Brand 	/* The size "must account for the zero terminator" */
521*b0104773SPascal Brand 	*nameBufferLen = l + 1;
522*b0104773SPascal Brand 
523*b0104773SPascal Brand 	if (l >= bufferlen)
524*b0104773SPascal Brand 		return TEE_ERROR_SHORT_BUFFER;
525*b0104773SPascal Brand 
526*b0104773SPascal Brand 	return TEE_SUCCESS;
527*b0104773SPascal Brand }
528*b0104773SPascal Brand 
529*b0104773SPascal Brand TEE_Result TEE_GetNextProperty(TEE_PropSetHandle enumerator)
530*b0104773SPascal Brand {
531*b0104773SPascal Brand 	TEE_Result res;
532*b0104773SPascal Brand 	struct prop_enumerator *pe = (struct prop_enumerator *)enumerator;
533*b0104773SPascal Brand 	uint32_t next_idx;
534*b0104773SPascal Brand 	const struct prop_set *ps;
535*b0104773SPascal Brand 	size_t ps_len;
536*b0104773SPascal Brand 	const struct user_ta_property *eps;
537*b0104773SPascal Brand 	size_t eps_len;
538*b0104773SPascal Brand 
539*b0104773SPascal Brand 	if (pe == NULL)
540*b0104773SPascal Brand 		return TEE_ERROR_BAD_PARAMETERS;
541*b0104773SPascal Brand 
542*b0104773SPascal Brand 	if (pe->idx == PROP_ENUMERATOR_NOT_STARTED)
543*b0104773SPascal Brand 		return TEE_ERROR_ITEM_NOT_FOUND;
544*b0104773SPascal Brand 
545*b0104773SPascal Brand 	res = propset_get(pe->prop_set, &ps, &ps_len, &eps, &eps_len);
546*b0104773SPascal Brand 	if (res != TEE_SUCCESS)
547*b0104773SPascal Brand 		return res;
548*b0104773SPascal Brand 
549*b0104773SPascal Brand 	next_idx = pe->idx + 1;
550*b0104773SPascal Brand 	pe->idx = next_idx;
551*b0104773SPascal Brand 	if (next_idx >= (ps_len + eps_len))
552*b0104773SPascal Brand 		return TEE_ERROR_ITEM_NOT_FOUND;
553*b0104773SPascal Brand 
554*b0104773SPascal Brand 	return TEE_SUCCESS;
555*b0104773SPascal Brand }
556