xref: /optee_os/ta/pkcs11/src/handle.c (revision b8fa5170281c08271ca243bd504cabedddfecd5b)
122ada947SEtienne Carriere // SPDX-License-Identifier: BSD-2-Clause
222ada947SEtienne Carriere /*
322ada947SEtienne Carriere  * Copyright (c) 2014-2020, Linaro Limited
422ada947SEtienne Carriere  */
522ada947SEtienne Carriere 
622ada947SEtienne Carriere #include <stdlib.h>
722ada947SEtienne Carriere #include <tee_internal_api.h>
822ada947SEtienne Carriere #include <tee_internal_api_extensions.h>
922ada947SEtienne Carriere 
1022ada947SEtienne Carriere #include "handle.h"
1122ada947SEtienne Carriere 
1222ada947SEtienne Carriere /*
1322ada947SEtienne Carriere  * Define the initial capacity of the database. It should be a low number
1422ada947SEtienne Carriere  * multiple of 2 since some databases a likely to only use a few handles.
1522ada947SEtienne Carriere  * Since the algorithm is to doubles up when growing it shouldn't cause a
1622ada947SEtienne Carriere  * noticeable overhead on large databases.
1722ada947SEtienne Carriere  */
1822ada947SEtienne Carriere #define HANDLE_DB_INITIAL_MAX_PTRS	4
1922ada947SEtienne Carriere 
2022ada947SEtienne Carriere void handle_db_init(struct handle_db *db)
2122ada947SEtienne Carriere {
2222ada947SEtienne Carriere 	TEE_MemFill(db, 0, sizeof(*db));
2322ada947SEtienne Carriere }
2422ada947SEtienne Carriere 
2522ada947SEtienne Carriere void handle_db_destroy(struct handle_db *db)
2622ada947SEtienne Carriere {
2722ada947SEtienne Carriere 	if (db) {
2822ada947SEtienne Carriere 		TEE_Free(db->ptrs);
2922ada947SEtienne Carriere 		db->ptrs = NULL;
3022ada947SEtienne Carriere 		db->max_ptrs = 0;
3122ada947SEtienne Carriere 	}
3222ada947SEtienne Carriere }
3322ada947SEtienne Carriere 
3422ada947SEtienne Carriere uint32_t handle_get(struct handle_db *db, void *ptr)
3522ada947SEtienne Carriere {
3622ada947SEtienne Carriere 	uint32_t n = 0;
3722ada947SEtienne Carriere 	void *p = NULL;
3822ada947SEtienne Carriere 	uint32_t new_max_ptrs = 0;
3922ada947SEtienne Carriere 
4022ada947SEtienne Carriere 	if (!db || !ptr)
4122ada947SEtienne Carriere 		return 0;
4222ada947SEtienne Carriere 
4322ada947SEtienne Carriere 	/* Try to find an empty location (index 0 is reserved as invalid) */
4422ada947SEtienne Carriere 	for (n = 1; n < db->max_ptrs; n++) {
4522ada947SEtienne Carriere 		if (!db->ptrs[n]) {
4622ada947SEtienne Carriere 			db->ptrs[n] = ptr;
4722ada947SEtienne Carriere 			return n;
4822ada947SEtienne Carriere 		}
4922ada947SEtienne Carriere 	}
5022ada947SEtienne Carriere 
5122ada947SEtienne Carriere 	/* No location available, grow the ptrs array */
5222ada947SEtienne Carriere 	if (db->max_ptrs)
5322ada947SEtienne Carriere 		new_max_ptrs = db->max_ptrs * 2;
5422ada947SEtienne Carriere 	else
5522ada947SEtienne Carriere 		new_max_ptrs = HANDLE_DB_INITIAL_MAX_PTRS;
5622ada947SEtienne Carriere 
5722ada947SEtienne Carriere 	p = TEE_Realloc(db->ptrs, new_max_ptrs * sizeof(void *));
5822ada947SEtienne Carriere 	if (!p)
5922ada947SEtienne Carriere 		return 0;
6022ada947SEtienne Carriere 	db->ptrs = p;
6122ada947SEtienne Carriere 	TEE_MemFill(db->ptrs + db->max_ptrs, 0,
6222ada947SEtienne Carriere 		    (new_max_ptrs - db->max_ptrs) * sizeof(void *));
6322ada947SEtienne Carriere 	db->max_ptrs = new_max_ptrs;
6422ada947SEtienne Carriere 
6522ada947SEtienne Carriere 	/* Since n stopped at db->max_ptrs there is an empty location there */
6622ada947SEtienne Carriere 	db->ptrs[n] = ptr;
6722ada947SEtienne Carriere 	return n;
6822ada947SEtienne Carriere }
6922ada947SEtienne Carriere 
70*b8fa5170SEtienne Carriere static bool handle_is_valid(struct handle_db *db, uint32_t handle)
71*b8fa5170SEtienne Carriere {
72*b8fa5170SEtienne Carriere 	return db && handle && handle < db->max_ptrs;
73*b8fa5170SEtienne Carriere }
74*b8fa5170SEtienne Carriere 
7522ada947SEtienne Carriere void *handle_put(struct handle_db *db, uint32_t handle)
7622ada947SEtienne Carriere {
7722ada947SEtienne Carriere 	void *p = NULL;
7822ada947SEtienne Carriere 
79*b8fa5170SEtienne Carriere 	if (!handle_is_valid(db, handle))
8022ada947SEtienne Carriere 		return NULL;
8122ada947SEtienne Carriere 
8222ada947SEtienne Carriere 	p = db->ptrs[handle];
8322ada947SEtienne Carriere 	db->ptrs[handle] = NULL;
8422ada947SEtienne Carriere 	return p;
8522ada947SEtienne Carriere }
8622ada947SEtienne Carriere 
8722ada947SEtienne Carriere void *handle_lookup(struct handle_db *db, uint32_t handle)
8822ada947SEtienne Carriere {
89*b8fa5170SEtienne Carriere 	if (!handle_is_valid(db, handle))
9022ada947SEtienne Carriere 		return NULL;
9122ada947SEtienne Carriere 
9222ada947SEtienne Carriere 	return db->ptrs[handle];
9322ada947SEtienne Carriere }
9422ada947SEtienne Carriere 
9522ada947SEtienne Carriere uint32_t handle_lookup_handle(struct handle_db *db, void *ptr)
9622ada947SEtienne Carriere {
9722ada947SEtienne Carriere 	uint32_t n = 0;
9822ada947SEtienne Carriere 
9922ada947SEtienne Carriere 	if (ptr) {
10022ada947SEtienne Carriere 		for (n = 1; n < db->max_ptrs; n++)
10122ada947SEtienne Carriere 			if (db->ptrs[n] == ptr)
10222ada947SEtienne Carriere 				return n;
10322ada947SEtienne Carriere 	}
10422ada947SEtienne Carriere 
10522ada947SEtienne Carriere 	return 0;
10622ada947SEtienne Carriere }
107