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