xref: /optee_os/lib/libutee/tee_api_property.c (revision 81d5a9d51511f52b8389c80b488f234b5d4d74aa)
11bb92983SJerome Forissier // SPDX-License-Identifier: BSD-2-Clause
2b0104773SPascal Brand /*
3b0104773SPascal Brand  * Copyright (c) 2014, STMicroelectronics International N.V.
46915bbbbSJens Wiklander  * Copyright (c) 2017-2020, Linaro Limited
5b0104773SPascal Brand  */
6*81d5a9d5SJens Wiklander #include <base64.h>
7a32a96edSJens Wiklander #include <printk.h>
8a32a96edSJens Wiklander #include <stdio.h>
9b0104773SPascal Brand #include <stdlib.h>
10b0104773SPascal Brand #include <string.h>
11*81d5a9d5SJens Wiklander #include <string_ext.h>
12a32a96edSJens Wiklander #include <tee_api.h>
13*81d5a9d5SJens Wiklander #include <tee_api_defines.h>
14b0104773SPascal Brand #include <tee_api_types.h>
15647f9c76SJerome Forissier #include <tee_arith_internal.h>
16a32a96edSJens Wiklander #include <tee_internal_api_extensions.h>
17a32a96edSJens Wiklander #include <tee_isocket.h>
18a32a96edSJens Wiklander #include <user_ta_header.h>
19b0104773SPascal Brand #include <utee_syscalls.h>
20a32a96edSJens Wiklander #include <util.h>
21b0104773SPascal Brand 
226915bbbbSJens Wiklander #include "tee_api_private.h"
23b0104773SPascal Brand 
24b0104773SPascal Brand #define PROP_STR_MAX    80
25b0104773SPascal Brand 
26b0104773SPascal Brand #define PROP_ENUMERATOR_NOT_STARTED 0xffffffff
27b0104773SPascal Brand 
28b0104773SPascal Brand struct prop_enumerator {
2964a5011eSPascal Brand 	uint32_t idx;			/* current index */
3064a5011eSPascal Brand 	TEE_PropSetHandle prop_set;	/* part of TEE_PROPSET_xxx */
31b0104773SPascal Brand };
32b0104773SPascal Brand 
3364a5011eSPascal Brand const struct user_ta_property tee_props[] = {
3464a5011eSPascal Brand 	{
3564a5011eSPascal Brand 		"gpd.tee.arith.maxBigIntSize",
3664a5011eSPascal Brand 		USER_TA_PROP_TYPE_U32,
37e3458e03SJerome Forissier 		&(const uint32_t){CFG_TA_BIGNUM_MAX_BITS}
3864a5011eSPascal Brand 	},
39a32a96edSJens Wiklander 	{
40a32a96edSJens Wiklander 		"gpd.tee.sockets.version",
41a32a96edSJens Wiklander 		USER_TA_PROP_TYPE_U32,
42a32a96edSJens Wiklander 		&(const uint32_t){TEE_ISOCKET_VERSION}
43a32a96edSJens Wiklander 	},
44a32a96edSJens Wiklander 	{
45a32a96edSJens Wiklander 		"gpd.tee.sockets.tcp.version",
46a32a96edSJens Wiklander 		USER_TA_PROP_TYPE_U32,
47a32a96edSJens Wiklander 		&(const uint32_t){TEE_ISOCKET_VERSION}
48a32a96edSJens Wiklander 	},
49094120adSJens Wiklander 	{
50094120adSJens Wiklander 		"gpd.tee.internalCore.version",
51094120adSJens Wiklander 		USER_TA_PROP_TYPE_U32,
52094120adSJens Wiklander 		&(const uint32_t){TEE_CORE_API_VERSION}
53094120adSJens Wiklander 	},
54b0104773SPascal Brand };
55b0104773SPascal Brand 
propset_get(TEE_PropSetHandle h,const struct user_ta_property ** eps,size_t * eps_len)5664a5011eSPascal Brand static TEE_Result propset_get(TEE_PropSetHandle h,
57b0104773SPascal Brand 			      const struct user_ta_property **eps,
58b0104773SPascal Brand 			      size_t *eps_len)
59b0104773SPascal Brand {
60b0104773SPascal Brand 	if (h == TEE_PROPSET_CURRENT_TA) {
61b0104773SPascal Brand 		*eps = ta_props;
62b0104773SPascal Brand 		*eps_len = ta_num_props;
63b0104773SPascal Brand 	} else if (h == TEE_PROPSET_CURRENT_CLIENT) {
64b0104773SPascal Brand 		*eps = NULL;
65b0104773SPascal Brand 		*eps_len = 0;
66b0104773SPascal Brand 	} else if (h == TEE_PROPSET_TEE_IMPLEMENTATION) {
6764a5011eSPascal Brand 		*eps = tee_props;
6864a5011eSPascal Brand 		*eps_len = ARRAY_SIZE(tee_props);
69b0104773SPascal Brand 	} else {
70b0104773SPascal Brand 		return TEE_ERROR_ITEM_NOT_FOUND;
71b0104773SPascal Brand 	}
72b0104773SPascal Brand 
73b0104773SPascal Brand 	return TEE_SUCCESS;
74b0104773SPascal Brand }
75b0104773SPascal Brand 
propget_get_ext_prop(const struct user_ta_property * ep,enum user_ta_prop_type * type,void * buf,uint32_t * len)76b0104773SPascal Brand static TEE_Result propget_get_ext_prop(const struct user_ta_property *ep,
77ff857a3aSPascal Brand 				       enum user_ta_prop_type *type,
78ff857a3aSPascal Brand 				       void *buf, uint32_t *len)
79b0104773SPascal Brand {
80b0104773SPascal Brand 	size_t l;
81b0104773SPascal Brand 
82ff857a3aSPascal Brand 	*type = ep->type;
83ff857a3aSPascal Brand 	switch (*type) {
84b0104773SPascal Brand 	case USER_TA_PROP_TYPE_BOOL:
85d5d50c3cSJens Wiklander 		l = sizeof(bool);
86b0104773SPascal Brand 		break;
87b0104773SPascal Brand 	case USER_TA_PROP_TYPE_U32:
88b0104773SPascal Brand 		l = sizeof(uint32_t);
89b0104773SPascal Brand 		break;
906551d565SJens Wiklander 	case USER_TA_PROP_TYPE_U64:
916551d565SJens Wiklander 		l = sizeof(uint64_t);
926551d565SJens Wiklander 		break;
93b0104773SPascal Brand 	case USER_TA_PROP_TYPE_UUID:
94b0104773SPascal Brand 		l = sizeof(TEE_UUID);
95b0104773SPascal Brand 		break;
96b0104773SPascal Brand 	case USER_TA_PROP_TYPE_IDENTITY:
97b0104773SPascal Brand 		l = sizeof(TEE_Identity);
98b0104773SPascal Brand 		break;
99b0104773SPascal Brand 	case USER_TA_PROP_TYPE_STRING:
100ff857a3aSPascal Brand 		/* take the leading 0 into account */
101ff857a3aSPascal Brand 		l = strlen(ep->value) + 1;
102ff857a3aSPascal Brand 		break;
103b0104773SPascal Brand 	case USER_TA_PROP_TYPE_BINARY_BLOCK:
104ff857a3aSPascal Brand 		/*
105ff857a3aSPascal Brand 		 * in case of TA property, a binary block is provided as a
106ff857a3aSPascal Brand 		 * string, which is base64 encoded. We must first decode it,
107ff857a3aSPascal Brand 		 * without taking into account the zero termination of the
108ff857a3aSPascal Brand 		 * string
109ff857a3aSPascal Brand 		 */
110ff857a3aSPascal Brand 		l = *len;
111*81d5a9d5SJens Wiklander 		if (!base64_dec(ep->value, strlen(ep->value), buf, &l) &&
112ec930caeSJerome Forissier 		    l <= *len)
113ff857a3aSPascal Brand 			return TEE_ERROR_GENERIC;
114ff857a3aSPascal Brand 		if (*len < l) {
115ff857a3aSPascal Brand 			*len = l;
116ff857a3aSPascal Brand 			return TEE_ERROR_SHORT_BUFFER;
117ff857a3aSPascal Brand 		}
118ff857a3aSPascal Brand 
119ff857a3aSPascal Brand 		*len = l;
120b0104773SPascal Brand 		return TEE_SUCCESS;
121b0104773SPascal Brand 	default:
122b0104773SPascal Brand 		return TEE_ERROR_GENERIC;
123b0104773SPascal Brand 	}
124ff857a3aSPascal Brand 
125ff857a3aSPascal Brand 	if (*len < l) {
126ff857a3aSPascal Brand 		*len = l;
127ff857a3aSPascal Brand 		return TEE_ERROR_SHORT_BUFFER;
128ff857a3aSPascal Brand 	}
129ff857a3aSPascal Brand 
130ff857a3aSPascal Brand 	*len = l;
131ff857a3aSPascal Brand 	memcpy(buf, ep->value, l);
132b0104773SPascal Brand 	return TEE_SUCCESS;
133b0104773SPascal Brand }
134b0104773SPascal Brand 
is_propset_pseudo_handle(TEE_PropSetHandle h)1356915bbbbSJens Wiklander static bool is_propset_pseudo_handle(TEE_PropSetHandle h)
1366915bbbbSJens Wiklander {
1376915bbbbSJens Wiklander 	return h == TEE_PROPSET_CURRENT_TA ||
1386915bbbbSJens Wiklander 	       h == TEE_PROPSET_CURRENT_CLIENT ||
1396915bbbbSJens Wiklander 	       h == TEE_PROPSET_TEE_IMPLEMENTATION;
1406915bbbbSJens Wiklander }
1416915bbbbSJens Wiklander 
propget_get_property(TEE_PropSetHandle h,const char * name,enum user_ta_prop_type * type,void * buf,uint32_t * len)1428f07fe6fSJerome Forissier static TEE_Result propget_get_property(TEE_PropSetHandle h, const char *name,
143ff857a3aSPascal Brand 				       enum user_ta_prop_type *type,
144ff857a3aSPascal Brand 				       void *buf, uint32_t *len)
145b0104773SPascal Brand {
146b0104773SPascal Brand 	TEE_Result res;
147b0104773SPascal Brand 	const struct user_ta_property *eps;
148b0104773SPascal Brand 	size_t eps_len;
14964a5011eSPascal Brand 	uint32_t prop_type;
15064a5011eSPascal Brand 	uint32_t index;
151b0104773SPascal Brand 
1526915bbbbSJens Wiklander 	if (is_propset_pseudo_handle(h)) {
153b0104773SPascal Brand 		size_t n;
154b0104773SPascal Brand 
15564a5011eSPascal Brand 		res = propset_get(h, &eps, &eps_len);
156b0104773SPascal Brand 		if (res != TEE_SUCCESS)
157b0104773SPascal Brand 			return res;
158b0104773SPascal Brand 
159b0104773SPascal Brand 		for (n = 0; n < eps_len; n++) {
16064a5011eSPascal Brand 			if (!strcmp(name, eps[n].name))
161ff857a3aSPascal Brand 				return propget_get_ext_prop(eps + n, type,
162ff857a3aSPascal Brand 							    buf, len);
163b0104773SPascal Brand 		}
16464a5011eSPascal Brand 
16564a5011eSPascal Brand 		/* get the index from the name */
1662c028fdeSJerome Forissier 		res = _utee_get_property_name_to_index((unsigned long)h, name,
1672c028fdeSJerome Forissier 						       strlen(name) + 1,
1682c028fdeSJerome Forissier 						       &index);
16964a5011eSPascal Brand 		if (res != TEE_SUCCESS)
17064a5011eSPascal Brand 			return res;
1712c028fdeSJerome Forissier 		res = _utee_get_property((unsigned long)h, index, NULL, NULL,
172ff857a3aSPascal Brand 					 buf, len, &prop_type);
173b0104773SPascal Brand 	} else {
174b0104773SPascal Brand 		struct prop_enumerator *pe = (struct prop_enumerator *)h;
175b0104773SPascal Brand 		uint32_t idx = pe->idx;
176b0104773SPascal Brand 
177b0104773SPascal Brand 		if (idx == PROP_ENUMERATOR_NOT_STARTED)
178b0104773SPascal Brand 			return TEE_ERROR_ITEM_NOT_FOUND;
179b0104773SPascal Brand 
18064a5011eSPascal Brand 		res = propset_get(pe->prop_set, &eps, &eps_len);
181b0104773SPascal Brand 		if (res != TEE_SUCCESS)
182b0104773SPascal Brand 			return res;
183b0104773SPascal Brand 
184b0104773SPascal Brand 		if (idx < eps_len)
185ff857a3aSPascal Brand 			return propget_get_ext_prop(eps + idx, type, buf, len);
18664a5011eSPascal Brand 		idx -= eps_len;
187b0104773SPascal Brand 
1882c028fdeSJerome Forissier 		res = _utee_get_property((unsigned long)pe->prop_set, idx,
189ff857a3aSPascal Brand 					 NULL, NULL, buf, len, &prop_type);
19064a5011eSPascal Brand 		if (res == TEE_ERROR_ITEM_NOT_FOUND)
19164a5011eSPascal Brand 			res = TEE_ERROR_BAD_PARAMETERS;
192b0104773SPascal Brand 	}
19364a5011eSPascal Brand 
194ff857a3aSPascal Brand 	*type = prop_type;
19564a5011eSPascal Brand 	return res;
196b0104773SPascal Brand }
197b0104773SPascal Brand 
TEE_GetPropertyAsString(TEE_PropSetHandle propsetOrEnumerator,const char * name,char * value,size_t * value_len)198b0104773SPascal Brand TEE_Result TEE_GetPropertyAsString(TEE_PropSetHandle propsetOrEnumerator,
1998f07fe6fSJerome Forissier 				   const char *name, char *value,
2006551d565SJens Wiklander 				   size_t *value_len)
201b0104773SPascal Brand {
2024d6266daSClement Faure 	TEE_Result res = TEE_ERROR_GENERIC;
2034d6266daSClement Faure 	size_t l = 0;
204a1f2c430SClement Faure 	enum user_ta_prop_type type = USER_TA_PROP_TYPE_INVALID;
205ff857a3aSPascal Brand 	void *tmp_buf = 0;
2064d6266daSClement Faure 	uint32_t tmp_len = 0;
2074d6266daSClement Faure 	uint32_t uint32_val = 0;
2084d6266daSClement Faure 	bool bool_val = false;
2094d6266daSClement Faure 	TEE_Identity *p_identity_val = NULL;
210b0104773SPascal Brand 
2116915bbbbSJens Wiklander 	if (is_propset_pseudo_handle(propsetOrEnumerator))
2126915bbbbSJens Wiklander 		__utee_check_instring_annotation(name);
2136915bbbbSJens Wiklander 	__utee_check_outstring_annotation(value, value_len);
214b0104773SPascal Brand 
2150dd3f3a4SPascal Brand 	tmp_len = *value_len;
216ff857a3aSPascal Brand 	if (tmp_len < sizeof(TEE_Identity))
217ff857a3aSPascal Brand 		tmp_len = sizeof(TEE_Identity);
218ff857a3aSPascal Brand 	tmp_buf = TEE_Malloc(tmp_len, TEE_USER_MEM_HINT_NO_FILL_ZERO);
219ff857a3aSPascal Brand 	if (!tmp_buf) {
220ff857a3aSPascal Brand 		res = TEE_ERROR_OUT_OF_MEMORY;
221ff857a3aSPascal Brand 		goto out;
222ff857a3aSPascal Brand 	}
223b0104773SPascal Brand 
224ff857a3aSPascal Brand 	res = propget_get_property(propsetOrEnumerator, name, &type,
225ff857a3aSPascal Brand 				   tmp_buf, &tmp_len);
226ff857a3aSPascal Brand 	if (res != TEE_SUCCESS) {
227254e1d58SPascal Brand 		if (res == TEE_ERROR_SHORT_BUFFER) {
228254e1d58SPascal Brand 			if (type == USER_TA_PROP_TYPE_BINARY_BLOCK) {
229254e1d58SPascal Brand 				/*
230254e1d58SPascal Brand 				 * in this case, we must enlarge the buffer
231254e1d58SPascal Brand 				 * with the size of the of the base64 encoded
232254e1d58SPascal Brand 				 * see base64_enc() function
233254e1d58SPascal Brand 				 */
234*81d5a9d5SJens Wiklander 				tmp_len = base64_enc_len(tmp_len);
235254e1d58SPascal Brand 			}
2360dd3f3a4SPascal Brand 			*value_len = tmp_len;
237254e1d58SPascal Brand 		}
238ff857a3aSPascal Brand 		goto out;
239ff857a3aSPascal Brand 	}
240b0104773SPascal Brand 
241ff857a3aSPascal Brand 	switch (type) {
242b0104773SPascal Brand 	case USER_TA_PROP_TYPE_BOOL:
243d5d50c3cSJens Wiklander 		bool_val = *((bool *)tmp_buf);
244d5d50c3cSJens Wiklander 		l = strlcpy(value, (bool_val ? "true" : "false"), *value_len);
245b0104773SPascal Brand 		break;
246b0104773SPascal Brand 
247b0104773SPascal Brand 	case USER_TA_PROP_TYPE_U32:
248ff857a3aSPascal Brand 		uint32_val = *((uint32_t *)tmp_buf);
2490dd3f3a4SPascal Brand 		l = snprintf(value, *value_len, "%u", uint32_val);
250b0104773SPascal Brand 		break;
251b0104773SPascal Brand 
252b0104773SPascal Brand 	case USER_TA_PROP_TYPE_UUID:
2530dd3f3a4SPascal Brand 		l = snprintk(value, *value_len, "%pUl", tmp_buf);
254b0104773SPascal Brand 		break;
255b0104773SPascal Brand 
256b0104773SPascal Brand 	case USER_TA_PROP_TYPE_IDENTITY:
257ff857a3aSPascal Brand 		p_identity_val = ((TEE_Identity *)tmp_buf);
2580dd3f3a4SPascal Brand 		l = snprintk(value, *value_len, "%u:%pUl",
259ff857a3aSPascal Brand 			     p_identity_val->login,
260ff857a3aSPascal Brand 			     (void *)(&(p_identity_val->uuid)));
261b0104773SPascal Brand 		break;
262b0104773SPascal Brand 
263b0104773SPascal Brand 	case USER_TA_PROP_TYPE_STRING:
2640dd3f3a4SPascal Brand 		l = strlcpy(value, tmp_buf, *value_len);
265ff857a3aSPascal Brand 		break;
266ff857a3aSPascal Brand 
267b0104773SPascal Brand 	case USER_TA_PROP_TYPE_BINARY_BLOCK:
2680dd3f3a4SPascal Brand 		l = *value_len;	/* l includes the zero-termination */
269*81d5a9d5SJens Wiklander 		if (!base64_enc(tmp_buf, tmp_len, value, &l) &&
270ec930caeSJerome Forissier 		    l <= *value_len) {
271ff857a3aSPascal Brand 			res = TEE_ERROR_GENERIC;
272ff857a3aSPascal Brand 			goto out;
273ff857a3aSPascal Brand 		}
274ff857a3aSPascal Brand 		l--;	/* remove the zero-termination that is added later */
275b0104773SPascal Brand 		break;
276b0104773SPascal Brand 
277b0104773SPascal Brand 	default:
278ba675d69SCedric Chaumont 		res = TEE_ERROR_BAD_FORMAT;
279ba675d69SCedric Chaumont 		goto out;
280ff857a3aSPascal Brand 	}
281ba675d69SCedric Chaumont 
282ff857a3aSPascal Brand 	l++;	/* include zero termination */
283ff857a3aSPascal Brand 
2840dd3f3a4SPascal Brand 	if (l > *value_len)
285ff857a3aSPascal Brand 		res = TEE_ERROR_SHORT_BUFFER;
2860dd3f3a4SPascal Brand 	*value_len = l;
287ff857a3aSPascal Brand 
288ba675d69SCedric Chaumont out:
289ff857a3aSPascal Brand 	if (tmp_buf)
290ff857a3aSPascal Brand 		TEE_Free(tmp_buf);
291ff857a3aSPascal Brand 	if (res != TEE_SUCCESS &&
292ff857a3aSPascal Brand 	    res != TEE_ERROR_ITEM_NOT_FOUND &&
293ff857a3aSPascal Brand 	    res != TEE_ERROR_SHORT_BUFFER)
294ff857a3aSPascal Brand 		TEE_Panic(0);
295ff857a3aSPascal Brand 
296ff857a3aSPascal Brand 	return res;
297b0104773SPascal Brand }
298b0104773SPascal Brand 
__GP11_TEE_GetPropertyAsString(TEE_PropSetHandle propsetOrEnumerator,const char * name,char * valueBuffer,uint32_t * valueBufferLen)2996551d565SJens Wiklander TEE_Result __GP11_TEE_GetPropertyAsString(TEE_PropSetHandle propsetOrEnumerator,
3006551d565SJens Wiklander 					  const char *name, char *valueBuffer,
3016551d565SJens Wiklander 					  uint32_t *valueBufferLen)
3026551d565SJens Wiklander {
3036551d565SJens Wiklander 	TEE_Result res = TEE_SUCCESS;
3046551d565SJens Wiklander 	size_t l = 0;
3056551d565SJens Wiklander 
3066551d565SJens Wiklander 	__utee_check_gp11_outstring_annotation(valueBuffer, valueBufferLen);
3076551d565SJens Wiklander 	l = *valueBufferLen;
3086551d565SJens Wiklander 	res = TEE_GetPropertyAsString(propsetOrEnumerator, name, valueBuffer,
3096551d565SJens Wiklander 				      &l);
3106551d565SJens Wiklander 	*valueBufferLen = l;
3116551d565SJens Wiklander 	return res;
3126551d565SJens Wiklander }
3136551d565SJens Wiklander 
TEE_GetPropertyAsBool(TEE_PropSetHandle propsetOrEnumerator,const char * name,bool * value)314b0104773SPascal Brand TEE_Result TEE_GetPropertyAsBool(TEE_PropSetHandle propsetOrEnumerator,
3158f07fe6fSJerome Forissier 				 const char *name, bool *value)
316b0104773SPascal Brand {
317b0104773SPascal Brand 	TEE_Result res;
318ff857a3aSPascal Brand 	enum user_ta_prop_type type;
319d5d50c3cSJens Wiklander 	uint32_t bool_len = sizeof(bool);
3206915bbbbSJens Wiklander 
3216915bbbbSJens Wiklander 	if (is_propset_pseudo_handle(propsetOrEnumerator))
3226915bbbbSJens Wiklander 		__utee_check_instring_annotation(name);
3236915bbbbSJens Wiklander 	__utee_check_out_annotation(value, sizeof(*value));
324b0104773SPascal Brand 
325ff857a3aSPascal Brand 	type = USER_TA_PROP_TYPE_BOOL;
326ff857a3aSPascal Brand 	res = propget_get_property(propsetOrEnumerator, name, &type,
327d5d50c3cSJens Wiklander 				   value, &bool_len);
328ff857a3aSPascal Brand 	if (type != USER_TA_PROP_TYPE_BOOL)
329ba675d69SCedric Chaumont 		res = TEE_ERROR_BAD_FORMAT;
330ff857a3aSPascal Brand 	if (res != TEE_SUCCESS)
331ba675d69SCedric Chaumont 		goto out;
332ba675d69SCedric Chaumont 
333ba675d69SCedric Chaumont out:
334ff857a3aSPascal Brand 	if (res != TEE_SUCCESS &&
335ff857a3aSPascal Brand 	    res != TEE_ERROR_ITEM_NOT_FOUND &&
336ff857a3aSPascal Brand 	    res != TEE_ERROR_BAD_FORMAT)
337ff857a3aSPascal Brand 		TEE_Panic(0);
338ff857a3aSPascal Brand 
339ff857a3aSPascal Brand 	return res;
340b0104773SPascal Brand }
341b0104773SPascal Brand 
TEE_GetPropertyAsU32(TEE_PropSetHandle propsetOrEnumerator,const char * name,uint32_t * value)342b0104773SPascal Brand TEE_Result TEE_GetPropertyAsU32(TEE_PropSetHandle propsetOrEnumerator,
3438f07fe6fSJerome Forissier 				const char *name, uint32_t *value)
344b0104773SPascal Brand {
345b0104773SPascal Brand 	TEE_Result res;
346ff857a3aSPascal Brand 	enum user_ta_prop_type type;
347ff857a3aSPascal Brand 	uint32_t uint32_len = sizeof(uint32_t);
348b0104773SPascal Brand 
3496915bbbbSJens Wiklander 	if (is_propset_pseudo_handle(propsetOrEnumerator))
3506915bbbbSJens Wiklander 		__utee_check_instring_annotation(name);
3516915bbbbSJens Wiklander 	__utee_check_out_annotation(value, sizeof(*value));
352ba675d69SCedric Chaumont 
353ff857a3aSPascal Brand 	type = USER_TA_PROP_TYPE_U32;
354ff857a3aSPascal Brand 	res = propget_get_property(propsetOrEnumerator, name, &type,
355ff857a3aSPascal Brand 				   value, &uint32_len);
356ff857a3aSPascal Brand 	if (type != USER_TA_PROP_TYPE_U32)
357ff857a3aSPascal Brand 		res = TEE_ERROR_BAD_FORMAT;
358ff857a3aSPascal Brand 
359ff857a3aSPascal Brand 	if (res != TEE_SUCCESS &&
360ff857a3aSPascal Brand 	    res != TEE_ERROR_ITEM_NOT_FOUND &&
361ff857a3aSPascal Brand 	    res != TEE_ERROR_BAD_FORMAT)
362ff857a3aSPascal Brand 		TEE_Panic(0);
363ff857a3aSPascal Brand 
364ff857a3aSPascal Brand 	return res;
365b0104773SPascal Brand }
366b0104773SPascal Brand 
TEE_GetPropertyAsU64(TEE_PropSetHandle propsetOrEnumerator,const char * name,uint64_t * value)3676551d565SJens Wiklander TEE_Result TEE_GetPropertyAsU64(TEE_PropSetHandle propsetOrEnumerator,
3686551d565SJens Wiklander 				const char *name, uint64_t *value)
369b0104773SPascal Brand {
370b0104773SPascal Brand 	TEE_Result res;
371ff857a3aSPascal Brand 	enum user_ta_prop_type type;
3726551d565SJens Wiklander 	uint32_t uint64_len = sizeof(*value);
373b0104773SPascal Brand 
3746915bbbbSJens Wiklander 	if (is_propset_pseudo_handle(propsetOrEnumerator))
3756915bbbbSJens Wiklander 		__utee_check_instring_annotation(name);
3766551d565SJens Wiklander 	__utee_check_out_annotation(value, sizeof(*value));
3776551d565SJens Wiklander 
3786551d565SJens Wiklander 	type = USER_TA_PROP_TYPE_U64;
3796551d565SJens Wiklander 	res = propget_get_property(propsetOrEnumerator, name, &type,
3806551d565SJens Wiklander 				   value, &uint64_len);
3816551d565SJens Wiklander 	if (type != USER_TA_PROP_TYPE_U64)
3826551d565SJens Wiklander 		res = TEE_ERROR_BAD_FORMAT;
3836551d565SJens Wiklander 
3846551d565SJens Wiklander 	if (res != TEE_SUCCESS &&
3856551d565SJens Wiklander 	    res != TEE_ERROR_ITEM_NOT_FOUND &&
3866551d565SJens Wiklander 	    res != TEE_ERROR_BAD_FORMAT)
3876551d565SJens Wiklander 		TEE_Panic(0);
3886551d565SJens Wiklander 
3896551d565SJens Wiklander 	return res;
3906551d565SJens Wiklander }
3916551d565SJens Wiklander 
3926551d565SJens Wiklander TEE_Result
__GP11_TEE_GetPropertyAsBinaryBlock(TEE_PropSetHandle propsetOrEnumerator,const char * name,void * value,uint32_t * value_len)3936551d565SJens Wiklander __GP11_TEE_GetPropertyAsBinaryBlock(TEE_PropSetHandle propsetOrEnumerator,
3946551d565SJens Wiklander 				    const char *name, void *value,
3956551d565SJens Wiklander 				    uint32_t *value_len)
3966551d565SJens Wiklander {
3976551d565SJens Wiklander 	TEE_Result res = TEE_SUCCESS;
3986551d565SJens Wiklander 	enum user_ta_prop_type type = USER_TA_PROP_TYPE_BOOL;
3996551d565SJens Wiklander 
4006551d565SJens Wiklander 	if (is_propset_pseudo_handle(propsetOrEnumerator))
4016551d565SJens Wiklander 		__utee_check_instring_annotation(name);
4026551d565SJens Wiklander 	__utee_check_gp11_outbuf_annotation(value, value_len);
403ba675d69SCedric Chaumont 
404ff857a3aSPascal Brand 	type = USER_TA_PROP_TYPE_BINARY_BLOCK;
405ff857a3aSPascal Brand 	res = propget_get_property(propsetOrEnumerator, name, &type,
4060dd3f3a4SPascal Brand 				   value, value_len);
407ff857a3aSPascal Brand 	if (type != USER_TA_PROP_TYPE_BINARY_BLOCK)
408ff857a3aSPascal Brand 		res = TEE_ERROR_BAD_FORMAT;
409ff857a3aSPascal Brand 
410ff857a3aSPascal Brand 	if (res != TEE_SUCCESS &&
411ff857a3aSPascal Brand 	    res != TEE_ERROR_ITEM_NOT_FOUND &&
412ff857a3aSPascal Brand 	    res != TEE_ERROR_BAD_FORMAT &&
413ff857a3aSPascal Brand 	    res != TEE_ERROR_SHORT_BUFFER)
414ff857a3aSPascal Brand 		TEE_Panic(0);
415ff857a3aSPascal Brand 
416ff857a3aSPascal Brand 	return res;
417b0104773SPascal Brand }
418b0104773SPascal Brand 
TEE_GetPropertyAsBinaryBlock(TEE_PropSetHandle propsetOrEnumerator,const char * name,void * value,size_t * value_len)4196551d565SJens Wiklander TEE_Result TEE_GetPropertyAsBinaryBlock(TEE_PropSetHandle propsetOrEnumerator,
4206551d565SJens Wiklander 					const char *name, void *value,
4216551d565SJens Wiklander 					size_t *value_len)
4226551d565SJens Wiklander {
4236551d565SJens Wiklander 	TEE_Result res = TEE_SUCCESS;
4246551d565SJens Wiklander 	uint32_t l = 0;
4256551d565SJens Wiklander 
4266551d565SJens Wiklander 	__utee_check_outbuf_annotation(value, value_len);
4276551d565SJens Wiklander 	l = *value_len;
4286551d565SJens Wiklander 	res = __GP11_TEE_GetPropertyAsBinaryBlock(propsetOrEnumerator, name,
4296551d565SJens Wiklander 						  value, &l);
4306551d565SJens Wiklander 	*value_len = l;
4316551d565SJens Wiklander 	return res;
4326551d565SJens Wiklander }
4336551d565SJens Wiklander 
TEE_GetPropertyAsUUID(TEE_PropSetHandle propsetOrEnumerator,const char * name,TEE_UUID * value)434b0104773SPascal Brand TEE_Result TEE_GetPropertyAsUUID(TEE_PropSetHandle propsetOrEnumerator,
4358f07fe6fSJerome Forissier 				 const char *name, TEE_UUID *value)
436b0104773SPascal Brand {
437b0104773SPascal Brand 	TEE_Result res;
438ff857a3aSPascal Brand 	enum user_ta_prop_type type;
439ff857a3aSPascal Brand 	uint32_t uuid_len = sizeof(TEE_UUID);
440b0104773SPascal Brand 
4416915bbbbSJens Wiklander 	if (is_propset_pseudo_handle(propsetOrEnumerator))
4426915bbbbSJens Wiklander 		__utee_check_instring_annotation(name);
4436915bbbbSJens Wiklander 	__utee_check_out_annotation(value, sizeof(*value));
444ba675d69SCedric Chaumont 
445ff857a3aSPascal Brand 	type = USER_TA_PROP_TYPE_UUID;
446ff857a3aSPascal Brand 	res = propget_get_property(propsetOrEnumerator, name, &type,
447ff857a3aSPascal Brand 				   value, &uuid_len);
448ff857a3aSPascal Brand 	if (type != USER_TA_PROP_TYPE_UUID)
449ff857a3aSPascal Brand 		res = TEE_ERROR_BAD_FORMAT;
450ff857a3aSPascal Brand 
451ff857a3aSPascal Brand 	if (res != TEE_SUCCESS &&
452ff857a3aSPascal Brand 	    res != TEE_ERROR_ITEM_NOT_FOUND &&
453ff857a3aSPascal Brand 	    res != TEE_ERROR_BAD_FORMAT)
454ff857a3aSPascal Brand 		TEE_Panic(0);
455ff857a3aSPascal Brand 
456ff857a3aSPascal Brand 	return res;
457b0104773SPascal Brand }
458b0104773SPascal Brand 
TEE_GetPropertyAsIdentity(TEE_PropSetHandle propsetOrEnumerator,const char * name,TEE_Identity * value)459b0104773SPascal Brand TEE_Result TEE_GetPropertyAsIdentity(TEE_PropSetHandle propsetOrEnumerator,
4608f07fe6fSJerome Forissier 				     const char *name, TEE_Identity *value)
461b0104773SPascal Brand {
462b0104773SPascal Brand 	TEE_Result res;
463ff857a3aSPascal Brand 	enum user_ta_prop_type type;
464ff857a3aSPascal Brand 	uint32_t identity_len = sizeof(TEE_Identity);
465b0104773SPascal Brand 
4666915bbbbSJens Wiklander 	if (is_propset_pseudo_handle(propsetOrEnumerator))
4676915bbbbSJens Wiklander 		__utee_check_instring_annotation(name);
4686915bbbbSJens Wiklander 	__utee_check_out_annotation(value, sizeof(*value));
469ba675d69SCedric Chaumont 
470ff857a3aSPascal Brand 	type = USER_TA_PROP_TYPE_IDENTITY;
471ff857a3aSPascal Brand 	res = propget_get_property(propsetOrEnumerator, name, &type,
472ff857a3aSPascal Brand 				   value, &identity_len);
473ff857a3aSPascal Brand 	if (type != USER_TA_PROP_TYPE_IDENTITY)
474ff857a3aSPascal Brand 		res = TEE_ERROR_BAD_FORMAT;
475ff857a3aSPascal Brand 
476ff857a3aSPascal Brand 	if (res != TEE_SUCCESS &&
477ff857a3aSPascal Brand 	    res != TEE_ERROR_ITEM_NOT_FOUND &&
478ff857a3aSPascal Brand 	    res != TEE_ERROR_BAD_FORMAT)
479ff857a3aSPascal Brand 		TEE_Panic(0);
480ff857a3aSPascal Brand 
481ff857a3aSPascal Brand 	return res;
482b0104773SPascal Brand }
483b0104773SPascal Brand 
TEE_AllocatePropertyEnumerator(TEE_PropSetHandle * enumerator)484b0104773SPascal Brand TEE_Result TEE_AllocatePropertyEnumerator(TEE_PropSetHandle *enumerator)
485b0104773SPascal Brand {
486ba675d69SCedric Chaumont 	TEE_Result res;
487b0104773SPascal Brand 	struct prop_enumerator *pe;
488b0104773SPascal Brand 
4896915bbbbSJens Wiklander 	__utee_check_out_annotation(enumerator, sizeof(*enumerator));
490b0104773SPascal Brand 
491b0104773SPascal Brand 	pe = TEE_Malloc(sizeof(struct prop_enumerator),
492b0104773SPascal Brand 			TEE_USER_MEM_HINT_NO_FILL_ZERO);
493ba675d69SCedric Chaumont 	if (pe == NULL) {
494ba675d69SCedric Chaumont 		res = TEE_ERROR_OUT_OF_MEMORY;
495ba675d69SCedric Chaumont 		goto err;
496ba675d69SCedric Chaumont 	}
497b0104773SPascal Brand 
498b0104773SPascal Brand 	*enumerator = (TEE_PropSetHandle) pe;
499b0104773SPascal Brand 	TEE_ResetPropertyEnumerator(*enumerator);
500ba675d69SCedric Chaumont 
501ba675d69SCedric Chaumont 	goto out;
502ba675d69SCedric Chaumont 
503ba675d69SCedric Chaumont err:
504ba675d69SCedric Chaumont 	if (res == TEE_ERROR_OUT_OF_MEMORY)
505ba675d69SCedric Chaumont 		return res;
506ba675d69SCedric Chaumont 	TEE_Panic(0);
507ba675d69SCedric Chaumont out:
508b0104773SPascal Brand 	return TEE_SUCCESS;
509b0104773SPascal Brand }
510b0104773SPascal Brand 
TEE_ResetPropertyEnumerator(TEE_PropSetHandle enumerator)511b0104773SPascal Brand void TEE_ResetPropertyEnumerator(TEE_PropSetHandle enumerator)
512b0104773SPascal Brand {
513b0104773SPascal Brand 	struct prop_enumerator *pe = (struct prop_enumerator *)enumerator;
514b0104773SPascal Brand 
515b0104773SPascal Brand 	pe->idx = PROP_ENUMERATOR_NOT_STARTED;
516b0104773SPascal Brand }
517b0104773SPascal Brand 
TEE_FreePropertyEnumerator(TEE_PropSetHandle enumerator)518b0104773SPascal Brand void TEE_FreePropertyEnumerator(TEE_PropSetHandle enumerator)
519b0104773SPascal Brand {
520b0104773SPascal Brand 	struct prop_enumerator *pe = (struct prop_enumerator *)enumerator;
521b0104773SPascal Brand 
522b0104773SPascal Brand 	TEE_Free(pe);
523b0104773SPascal Brand }
524b0104773SPascal Brand 
TEE_StartPropertyEnumerator(TEE_PropSetHandle enumerator,TEE_PropSetHandle propSet)525b0104773SPascal Brand void TEE_StartPropertyEnumerator(TEE_PropSetHandle enumerator,
526b0104773SPascal Brand 				 TEE_PropSetHandle propSet)
527b0104773SPascal Brand {
528b0104773SPascal Brand 	struct prop_enumerator *pe = (struct prop_enumerator *)enumerator;
529b0104773SPascal Brand 
5300dd3f3a4SPascal Brand 	if (!pe)
531b0104773SPascal Brand 		return;
532b0104773SPascal Brand 
533b0104773SPascal Brand 	pe->idx = 0;
534b0104773SPascal Brand 	pe->prop_set = propSet;
535b0104773SPascal Brand }
536b0104773SPascal Brand 
__GP11_TEE_GetPropertyName(TEE_PropSetHandle enumerator,void * name,uint32_t * name_len)5376551d565SJens Wiklander TEE_Result __GP11_TEE_GetPropertyName(TEE_PropSetHandle enumerator,
5380dd3f3a4SPascal Brand 				      void *name, uint32_t *name_len)
539b0104773SPascal Brand {
540b0104773SPascal Brand 	TEE_Result res;
541b0104773SPascal Brand 	struct prop_enumerator *pe = (struct prop_enumerator *)enumerator;
542b0104773SPascal Brand 	const struct user_ta_property *eps;
543b0104773SPascal Brand 	size_t eps_len;
544b0104773SPascal Brand 	const char *str;
545b0104773SPascal Brand 	size_t bufferlen;
546b0104773SPascal Brand 
5476915bbbbSJens Wiklander 	if (!pe) {
548ba675d69SCedric Chaumont 		res = TEE_ERROR_BAD_PARAMETERS;
549ba675d69SCedric Chaumont 		goto err;
550ba675d69SCedric Chaumont 	}
5516551d565SJens Wiklander 	__utee_check_gp11_outstring_annotation(name, name_len);
552b0104773SPascal Brand 
5530dd3f3a4SPascal Brand 	bufferlen = *name_len;
55464a5011eSPascal Brand 	res = propset_get(pe->prop_set, &eps, &eps_len);
555b0104773SPascal Brand 	if (res != TEE_SUCCESS)
556ba675d69SCedric Chaumont 		goto err;
557b0104773SPascal Brand 
55864a5011eSPascal Brand 	if (pe->idx < eps_len) {
55964a5011eSPascal Brand 		str = eps[pe->idx].name;
5600dd3f3a4SPascal Brand 		bufferlen = strlcpy(name, str, *name_len) + 1;
5610dd3f3a4SPascal Brand 		if (bufferlen > *name_len)
562ba675d69SCedric Chaumont 			res = TEE_ERROR_SHORT_BUFFER;
5630dd3f3a4SPascal Brand 		*name_len = bufferlen;
56464a5011eSPascal Brand 	} else {
5652c028fdeSJerome Forissier 		res = _utee_get_property((unsigned long)pe->prop_set,
5662c028fdeSJerome Forissier 					 pe->idx - eps_len, name, name_len,
5672c028fdeSJerome Forissier 					 NULL, NULL, NULL);
56864a5011eSPascal Brand 		if (res != TEE_SUCCESS)
569ba675d69SCedric Chaumont 			goto err;
570ba675d69SCedric Chaumont 	}
571b0104773SPascal Brand 
572ba675d69SCedric Chaumont err:
57364a5011eSPascal Brand 	if (res != TEE_SUCCESS &&
57464a5011eSPascal Brand 	    res != TEE_ERROR_ITEM_NOT_FOUND &&
57564a5011eSPascal Brand 	    res != TEE_ERROR_SHORT_BUFFER)
576ba675d69SCedric Chaumont 		TEE_Panic(0);
57764a5011eSPascal Brand 	return res;
578b0104773SPascal Brand }
579b0104773SPascal Brand 
TEE_GetPropertyName(TEE_PropSetHandle enumerator,void * nameBuffer,size_t * nameBufferLen)5806551d565SJens Wiklander TEE_Result TEE_GetPropertyName(TEE_PropSetHandle enumerator,
5816551d565SJens Wiklander 			       void *nameBuffer, size_t *nameBufferLen)
5826551d565SJens Wiklander {
5836551d565SJens Wiklander 	TEE_Result res = TEE_SUCCESS;
5846551d565SJens Wiklander 	uint32_t l = 0;
5856551d565SJens Wiklander 
5866551d565SJens Wiklander 	__utee_check_outstring_annotation(nameBuffer, nameBufferLen);
5876551d565SJens Wiklander 	l = *nameBufferLen;
5886551d565SJens Wiklander 	res = __GP11_TEE_GetPropertyName(enumerator, nameBuffer, &l);
5896551d565SJens Wiklander 	*nameBufferLen = l;
5906551d565SJens Wiklander 	return res;
5916551d565SJens Wiklander }
5926551d565SJens Wiklander 
TEE_GetNextProperty(TEE_PropSetHandle enumerator)593b0104773SPascal Brand TEE_Result TEE_GetNextProperty(TEE_PropSetHandle enumerator)
594b0104773SPascal Brand {
595b0104773SPascal Brand 	TEE_Result res;
596b0104773SPascal Brand 	struct prop_enumerator *pe = (struct prop_enumerator *)enumerator;
597b0104773SPascal Brand 	uint32_t next_idx;
598b0104773SPascal Brand 	const struct user_ta_property *eps;
599b0104773SPascal Brand 	size_t eps_len;
600b0104773SPascal Brand 
6010dd3f3a4SPascal Brand 	if (!pe) {
602ba675d69SCedric Chaumont 		res = TEE_ERROR_BAD_PARAMETERS;
60364a5011eSPascal Brand 		goto out;
604ba675d69SCedric Chaumont 	}
605b0104773SPascal Brand 
606ba675d69SCedric Chaumont 	if (pe->idx == PROP_ENUMERATOR_NOT_STARTED) {
607ba675d69SCedric Chaumont 		res = TEE_ERROR_ITEM_NOT_FOUND;
60864a5011eSPascal Brand 		goto out;
609ba675d69SCedric Chaumont 	}
610b0104773SPascal Brand 
61164a5011eSPascal Brand 	res = propset_get(pe->prop_set, &eps, &eps_len);
612b0104773SPascal Brand 	if (res != TEE_SUCCESS)
61364a5011eSPascal Brand 		goto out;
614b0104773SPascal Brand 
615b0104773SPascal Brand 	next_idx = pe->idx + 1;
616b0104773SPascal Brand 	pe->idx = next_idx;
61764a5011eSPascal Brand 	if (next_idx < eps_len)
61864a5011eSPascal Brand 		res = TEE_SUCCESS;
61964a5011eSPascal Brand 	else
6202c028fdeSJerome Forissier 		res = _utee_get_property((unsigned long)pe->prop_set,
6212c028fdeSJerome Forissier 					 next_idx - eps_len, NULL, NULL, NULL,
6222c028fdeSJerome Forissier 					 NULL, NULL);
623b0104773SPascal Brand 
624ba675d69SCedric Chaumont out:
62564a5011eSPascal Brand 	if (res != TEE_SUCCESS &&
62664a5011eSPascal Brand 	    res != TEE_ERROR_ITEM_NOT_FOUND)
62764a5011eSPascal Brand 		TEE_Panic(0);
62864a5011eSPascal Brand 	return res;
629b0104773SPascal Brand }
630