xref: /optee_os/ta/pkcs11/src/persistent_token.c (revision c185655eafaab6b4b27759812cd6633e1da9db12)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2018-2020, Linaro Limited
4  */
5 
6 #include <assert.h>
7 #include <pkcs11_ta.h>
8 #include <string.h>
9 #include <string_ext.h>
10 #include <tee_internal_api_extensions.h>
11 #include <util.h>
12 
13 #include "attributes.h"
14 #include "pkcs11_token.h"
15 #include "pkcs11_helpers.h"
16 
17 #define PERSISTENT_OBJECT_ID_LEN	32
18 
19 /*
20  * Token persistent objects
21  *
22  * The persistent objects are each identified by a UUID.
23  * The persistent object database stores the list of the UUIDs registered. For
24  * each it is expected that a file of ID "UUID" is stored in the TA secure
25  * storage.
26  */
27 static TEE_Result get_db_file_name(struct ck_token *token,
28 				   char *name, size_t size)
29 {
30 	int n = snprintf(name, size, "token.db.%u", get_token_id(token));
31 
32 	if (n < 0 || (size_t)n >= size)
33 		return TEE_ERROR_SECURITY;
34 	else
35 		return TEE_SUCCESS;
36 }
37 
38 static TEE_Result open_db_file(struct ck_token *token,
39 			       TEE_ObjectHandle *out_hdl)
40 {
41 	char file[PERSISTENT_OBJECT_ID_LEN] = { };
42 	TEE_Result res = TEE_ERROR_GENERIC;
43 
44 	res = get_db_file_name(token, file, sizeof(file));
45 	if (res)
46 		return res;
47 
48 	return TEE_OpenPersistentObject(TEE_STORAGE_PRIVATE, file, sizeof(file),
49 					TEE_DATA_FLAG_ACCESS_READ |
50 					TEE_DATA_FLAG_ACCESS_WRITE,
51 					out_hdl);
52 }
53 
54 void update_persistent_db(struct ck_token *token)
55 {
56 	TEE_Result res = TEE_ERROR_GENERIC;
57 	TEE_ObjectHandle db_hdl = TEE_HANDLE_NULL;
58 
59 	res = open_db_file(token, &db_hdl);
60 	if (res) {
61 		EMSG("Failed to open token persistent db: %#"PRIx32, res);
62 		TEE_Panic(0);
63 	}
64 	res = TEE_WriteObjectData(db_hdl, token->db_main,
65 				  sizeof(*token->db_main));
66 	if (res) {
67 		EMSG("Failed to write to token persistent db: %#"PRIx32, res);
68 		TEE_Panic(0);
69 	}
70 
71 	TEE_CloseObject(db_hdl);
72 }
73 
74 static enum pkcs11_rc do_hash(uint32_t user, const uint8_t *pin,
75 			      size_t pin_size, uint32_t salt,
76 			      uint8_t hash[TEE_MAX_HASH_SIZE])
77 {
78 	TEE_Result res = TEE_SUCCESS;
79 	TEE_OperationHandle oh = TEE_HANDLE_NULL;
80 	uint32_t sz = TEE_MAX_HASH_SIZE;
81 
82 	res = TEE_AllocateOperation(&oh, TEE_ALG_SHA256, TEE_MODE_DIGEST, 0);
83 	if (res)
84 		return tee2pkcs_error(res);
85 
86 	TEE_DigestUpdate(oh, &user, sizeof(user));
87 	TEE_DigestUpdate(oh, &salt, sizeof(salt));
88 	res = TEE_DigestDoFinal(oh, pin, pin_size, hash, &sz);
89 	TEE_FreeOperation(oh);
90 
91 	if (res)
92 		return PKCS11_CKR_GENERAL_ERROR;
93 
94 	memset(hash + sz, 0, TEE_MAX_HASH_SIZE - sz);
95 	return PKCS11_CKR_OK;
96 }
97 
98 enum pkcs11_rc hash_pin(enum pkcs11_user_type user, const uint8_t *pin,
99 			size_t pin_size, uint32_t *salt,
100 			uint8_t hash[TEE_MAX_HASH_SIZE])
101 {
102 	enum pkcs11_rc rc = PKCS11_CKR_OK;
103 	uint32_t s = 0;
104 
105 	TEE_GenerateRandom(&s, sizeof(s));
106 	if (!s)
107 		s++;
108 
109 	rc = do_hash(user, pin, pin_size, s, hash);
110 	if (!rc)
111 		*salt = s;
112 	return rc;
113 }
114 
115 enum pkcs11_rc verify_pin(enum pkcs11_user_type user, const uint8_t *pin,
116 			  size_t pin_size, uint32_t salt,
117 			  const uint8_t hash[TEE_MAX_HASH_SIZE])
118 {
119 	uint8_t tmp_hash[TEE_MAX_HASH_SIZE] = { 0 };
120 	enum pkcs11_rc rc = PKCS11_CKR_OK;
121 
122 	rc = do_hash(user, pin, pin_size, salt, tmp_hash);
123 	if (rc)
124 		return rc;
125 
126 	if (buf_compare_ct(tmp_hash, hash, TEE_MAX_HASH_SIZE))
127 		rc = PKCS11_CKR_PIN_INCORRECT;
128 
129 	return rc;
130 }
131 
132 #if defined(CFG_PKCS11_TA_AUTH_TEE_IDENTITY)
133 enum pkcs11_rc setup_so_identity_auth_from_client(struct ck_token *token)
134 {
135 	TEE_Identity identity = { };
136 	TEE_Result res = TEE_SUCCESS;
137 
138 	res = TEE_GetPropertyAsIdentity(TEE_PROPSET_CURRENT_CLIENT,
139 					"gpd.client.identity", &identity);
140 	if (res != TEE_SUCCESS) {
141 		EMSG("TEE_GetPropertyAsIdentity: returned %#"PRIx32, res);
142 		return PKCS11_CKR_PIN_INVALID;
143 	}
144 
145 	TEE_MemMove(&token->db_main->so_identity, &identity, sizeof(identity));
146 	token->db_main->flags |= PKCS11_CKFT_PROTECTED_AUTHENTICATION_PATH;
147 
148 	token->db_main->so_pin_salt = 0;
149 
150 	return PKCS11_CKR_OK;
151 }
152 
153 enum pkcs11_rc setup_identity_auth_from_pin(struct ck_token *token,
154 					    enum pkcs11_user_type user_type,
155 					    const uint8_t *pin,
156 					    size_t pin_size)
157 {
158 	TEE_Identity identity = { };
159 	TEE_Result res = TEE_SUCCESS;
160 	uint32_t flags_clear = 0;
161 	uint32_t flags_set = 0;
162 	char *acl_string = NULL;
163 	char *uuid_str = NULL;
164 
165 	assert(token->db_main->flags &
166 	       PKCS11_CKFT_PROTECTED_AUTHENTICATION_PATH);
167 
168 	if (!pin) {
169 		/* Use client identity */
170 		res = TEE_GetPropertyAsIdentity(TEE_PROPSET_CURRENT_CLIENT,
171 						"gpd.client.identity",
172 						&identity);
173 		if (res != TEE_SUCCESS) {
174 			EMSG("TEE_GetPropertyAsIdentity: returned %#"PRIx32,
175 			     res);
176 			return PKCS11_CKR_PIN_INVALID;
177 		}
178 	} else {
179 		/* Parse PIN ACL string: <login type>:<client id> */
180 		acl_string = TEE_Malloc(pin_size + 1, TEE_MALLOC_FILL_ZERO);
181 		if (!acl_string)
182 			return PKCS11_CKR_DEVICE_MEMORY;
183 		TEE_MemMove(acl_string, pin, pin_size);
184 
185 		uuid_str = strstr(acl_string, ":");
186 		if (uuid_str)
187 			uuid_str++;
188 		if (strcmp(PKCS11_AUTH_TEE_IDENTITY_PUBLIC, acl_string) == 0) {
189 			identity.login = TEE_LOGIN_PUBLIC;
190 		} else if (strstr(acl_string, PKCS11_AUTH_TEE_IDENTITY_USER) ==
191 			   acl_string) {
192 			identity.login = TEE_LOGIN_USER;
193 		} else if (strstr(acl_string, PKCS11_AUTH_TEE_IDENTITY_GROUP) ==
194 			   acl_string) {
195 			identity.login = TEE_LOGIN_GROUP;
196 		} else {
197 			EMSG("Invalid PIN ACL string - login");
198 			TEE_Free(acl_string);
199 			return PKCS11_CKR_PIN_INVALID;
200 		}
201 
202 		if (identity.login != TEE_LOGIN_PUBLIC) {
203 			if (!uuid_str) {
204 				EMSG("Invalid PIN ACL string - colon");
205 				TEE_Free(acl_string);
206 				return PKCS11_CKR_PIN_INVALID;
207 			}
208 
209 			res = tee_uuid_from_str(&identity.uuid, uuid_str);
210 			if (res) {
211 				EMSG("Invalid PIN ACL string - client id");
212 				TEE_Free(acl_string);
213 				return PKCS11_CKR_PIN_INVALID;
214 			}
215 		}
216 
217 		TEE_Free(acl_string);
218 	}
219 
220 	switch (user_type) {
221 	case PKCS11_CKU_SO:
222 		token->db_main->so_pin_count = 0;
223 		token->db_main->so_pin_salt = 0;
224 		flags_clear = PKCS11_CKFT_SO_PIN_COUNT_LOW |
225 			      PKCS11_CKFT_SO_PIN_FINAL_TRY |
226 			      PKCS11_CKFT_SO_PIN_LOCKED |
227 			      PKCS11_CKFT_SO_PIN_TO_BE_CHANGED;
228 
229 		TEE_MemMove(&token->db_main->so_identity, &identity,
230 			    sizeof(identity));
231 		break;
232 	case PKCS11_CKU_USER:
233 		token->db_main->user_pin_count = 0;
234 		token->db_main->user_pin_salt = 0;
235 		flags_clear = PKCS11_CKFT_USER_PIN_COUNT_LOW |
236 			      PKCS11_CKFT_USER_PIN_FINAL_TRY |
237 			      PKCS11_CKFT_USER_PIN_LOCKED |
238 			      PKCS11_CKFT_USER_PIN_TO_BE_CHANGED;
239 		flags_set = PKCS11_CKFT_USER_PIN_INITIALIZED;
240 
241 		TEE_MemMove(&token->db_main->user_identity, &identity,
242 			    sizeof(identity));
243 		break;
244 	default:
245 		return PKCS11_CKR_FUNCTION_FAILED;
246 	}
247 
248 	token->db_main->flags &= ~flags_clear;
249 	token->db_main->flags |= flags_set;
250 
251 	return PKCS11_CKR_OK;
252 }
253 
254 enum pkcs11_rc verify_identity_auth(struct ck_token *token,
255 				    enum pkcs11_user_type user_type)
256 {
257 	TEE_Identity identity = { };
258 	TEE_Result res = TEE_SUCCESS;
259 
260 	assert(token->db_main->flags &
261 	       PKCS11_CKFT_PROTECTED_AUTHENTICATION_PATH);
262 
263 	res = TEE_GetPropertyAsIdentity(TEE_PROPSET_CURRENT_CLIENT,
264 					"gpd.client.identity", &identity);
265 	if (res != TEE_SUCCESS) {
266 		EMSG("TEE_GetPropertyAsIdentity: returned %#"PRIx32, res);
267 		return PKCS11_CKR_PIN_INVALID;
268 	}
269 
270 	if (user_type == PKCS11_CKU_SO) {
271 		if (TEE_MemCompare(&token->db_main->so_identity, &identity,
272 				   sizeof(identity)))
273 			return PKCS11_CKR_PIN_INCORRECT;
274 	} else if (user_type == PKCS11_CKU_USER) {
275 		if (TEE_MemCompare(&token->db_main->user_identity, &identity,
276 				   sizeof(identity)))
277 			return PKCS11_CKR_PIN_INCORRECT;
278 	} else {
279 		return PKCS11_CKR_PIN_INCORRECT;
280 	}
281 
282 	return PKCS11_CKR_OK;
283 }
284 #endif /* CFG_PKCS11_TA_AUTH_TEE_IDENTITY */
285 
286 /*
287  * Release resources relate to persistent database
288  */
289 void close_persistent_db(struct ck_token *token __unused)
290 {
291 }
292 
293 static int get_persistent_obj_idx(struct ck_token *token, TEE_UUID *uuid)
294 {
295 	size_t i = 0;
296 
297 	if (!uuid)
298 		return -1;
299 
300 	for (i = 0; i < token->db_objs->count; i++)
301 		if (!TEE_MemCompare(token->db_objs->uuids + i,
302 				    uuid, sizeof(TEE_UUID)))
303 			return i;
304 
305 	return -1;
306 }
307 
308 /* UUID for persistent object */
309 enum pkcs11_rc create_object_uuid(struct ck_token *token,
310 				  struct pkcs11_object *obj)
311 {
312 	assert(!obj->uuid);
313 
314 	obj->uuid = TEE_Malloc(sizeof(TEE_UUID),
315 			       TEE_USER_MEM_HINT_NO_FILL_ZERO);
316 	if (!obj->uuid)
317 		return PKCS11_CKR_DEVICE_MEMORY;
318 
319 	do {
320 		TEE_GenerateRandom(obj->uuid, sizeof(TEE_UUID));
321 	} while (get_persistent_obj_idx(token, obj->uuid) >= 0);
322 
323 	return PKCS11_CKR_OK;
324 }
325 
326 void destroy_object_uuid(struct ck_token *token __maybe_unused,
327 			 struct pkcs11_object *obj)
328 {
329 	assert(get_persistent_obj_idx(token, obj->uuid) < 0);
330 
331 	TEE_Free(obj->uuid);
332 	obj->uuid = NULL;
333 }
334 
335 enum pkcs11_rc get_persistent_objects_list(struct ck_token *token,
336 					   TEE_UUID *array, size_t *size)
337 {
338 	size_t out_size = *size;
339 
340 	*size = token->db_objs->count * sizeof(TEE_UUID);
341 
342 	if (out_size < *size)
343 		return PKCS11_CKR_BUFFER_TOO_SMALL;
344 
345 	if (array)
346 		TEE_MemMove(array, token->db_objs->uuids, *size);
347 
348 	return PKCS11_CKR_OK;
349 }
350 
351 enum pkcs11_rc unregister_persistent_object(struct ck_token *token,
352 					    TEE_UUID *uuid)
353 {
354 	TEE_ObjectHandle db_hdl = TEE_HANDLE_NULL;
355 	struct token_persistent_objs *ptr = NULL;
356 	TEE_Result res = TEE_ERROR_GENERIC;
357 	int count = 0;
358 	int idx = 0;
359 
360 	if (!uuid)
361 		return PKCS11_CKR_OK;
362 
363 	idx = get_persistent_obj_idx(token, uuid);
364 	if (idx < 0) {
365 		DMSG("Cannot unregister an invalid persistent object");
366 		return PKCS11_RV_NOT_FOUND;
367 	}
368 
369 	ptr = TEE_Malloc(sizeof(struct token_persistent_objs) +
370 			 ((token->db_objs->count - 1) * sizeof(TEE_UUID)),
371 			 TEE_USER_MEM_HINT_NO_FILL_ZERO);
372 	if (!ptr)
373 		return PKCS11_CKR_DEVICE_MEMORY;
374 
375 	res = open_db_file(token, &db_hdl);
376 	if (res)
377 		goto out;
378 
379 	res = TEE_SeekObjectData(db_hdl, sizeof(struct token_persistent_main),
380 				 TEE_DATA_SEEK_SET);
381 	if (res) {
382 		DMSG("Failed to read database");
383 		goto out;
384 	}
385 
386 	TEE_MemMove(ptr, token->db_objs,
387 		    sizeof(struct token_persistent_objs) +
388 		    idx * sizeof(TEE_UUID));
389 
390 	ptr->count--;
391 	count = ptr->count - idx;
392 
393 	TEE_MemMove(&ptr->uuids[idx],
394 		    &token->db_objs->uuids[idx + 1],
395 		    count * sizeof(TEE_UUID));
396 
397 	res = TEE_WriteObjectData(db_hdl, ptr,
398 				  sizeof(struct token_persistent_objs) +
399 				  ptr->count * sizeof(TEE_UUID));
400 	if (res)
401 		DMSG("Failed to update database");
402 	TEE_Free(token->db_objs);
403 	token->db_objs = ptr;
404 	ptr = NULL;
405 
406 out:
407 	TEE_CloseObject(db_hdl);
408 	TEE_Free(ptr);
409 
410 	return tee2pkcs_error(res);
411 }
412 
413 enum pkcs11_rc register_persistent_object(struct ck_token *token,
414 					  TEE_UUID *uuid)
415 {
416 	TEE_ObjectHandle db_hdl = TEE_HANDLE_NULL;
417 	TEE_Result res = TEE_ERROR_GENERIC;
418 	void *ptr = NULL;
419 	size_t size = 0;
420 	int count = 0;
421 
422 	if (get_persistent_obj_idx(token, uuid) >= 0)
423 		TEE_Panic(0);
424 
425 	count = token->db_objs->count;
426 	ptr = TEE_Realloc(token->db_objs,
427 			  sizeof(struct token_persistent_objs) +
428 			  ((count + 1) * sizeof(TEE_UUID)));
429 	if (!ptr)
430 		return PKCS11_CKR_DEVICE_MEMORY;
431 
432 	token->db_objs = ptr;
433 	TEE_MemMove(token->db_objs->uuids + count, uuid, sizeof(TEE_UUID));
434 
435 	size = sizeof(struct token_persistent_main) +
436 	       sizeof(struct token_persistent_objs) +
437 	       count * sizeof(TEE_UUID);
438 
439 	res = open_db_file(token, &db_hdl);
440 	if (res)
441 		goto out;
442 
443 	res = TEE_TruncateObjectData(db_hdl, size + sizeof(TEE_UUID));
444 	if (res)
445 		goto out;
446 
447 	res = TEE_SeekObjectData(db_hdl, sizeof(struct token_persistent_main),
448 				 TEE_DATA_SEEK_SET);
449 	if (res)
450 		goto out;
451 
452 	token->db_objs->count++;
453 
454 	res = TEE_WriteObjectData(db_hdl, token->db_objs,
455 				  sizeof(struct token_persistent_objs) +
456 				  token->db_objs->count * sizeof(TEE_UUID));
457 	if (res)
458 		token->db_objs->count--;
459 
460 out:
461 	TEE_CloseObject(db_hdl);
462 
463 	return tee2pkcs_error(res);
464 }
465 
466 enum pkcs11_rc load_persistent_object_attributes(struct pkcs11_object *obj)
467 {
468 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
469 	TEE_Result res = TEE_ERROR_GENERIC;
470 	TEE_ObjectHandle hdl = obj->attribs_hdl;
471 	TEE_ObjectInfo info = { };
472 	struct obj_attrs *attr = NULL;
473 	uint32_t read_bytes = 0;
474 
475 	if (obj->attributes)
476 		return PKCS11_CKR_OK;
477 
478 	if (hdl == TEE_HANDLE_NULL) {
479 		res = TEE_OpenPersistentObject(TEE_STORAGE_PRIVATE,
480 					       obj->uuid, sizeof(*obj->uuid),
481 					       TEE_DATA_FLAG_ACCESS_READ, &hdl);
482 		if (res) {
483 			EMSG("OpenPersistent failed %#"PRIx32, res);
484 			return tee2pkcs_error(res);
485 		}
486 	}
487 
488 	TEE_MemFill(&info, 0, sizeof(info));
489 	res = TEE_GetObjectInfo1(hdl, &info);
490 	if (res) {
491 		EMSG("GetObjectInfo failed %#"PRIx32, res);
492 		rc = tee2pkcs_error(res);
493 		goto out;
494 	}
495 
496 	attr = TEE_Malloc(info.dataSize, TEE_MALLOC_FILL_ZERO);
497 	if (!attr) {
498 		rc = PKCS11_CKR_DEVICE_MEMORY;
499 		goto out;
500 	}
501 
502 	res = TEE_ReadObjectData(hdl, attr, info.dataSize, &read_bytes);
503 	if (!res) {
504 		res = TEE_SeekObjectData(hdl, 0, TEE_DATA_SEEK_SET);
505 		if (res)
506 			EMSG("Seek to 0 failed %#"PRIx32, res);
507 	}
508 
509 	if (res) {
510 		rc = tee2pkcs_error(res);
511 		EMSG("Read %"PRIu32" bytes, failed %#"PRIx32,
512 		     read_bytes, res);
513 		goto out;
514 	}
515 	if (read_bytes != info.dataSize) {
516 		EMSG("Read %"PRIu32" bytes, expected %"PRIu32,
517 		     read_bytes, info.dataSize);
518 		rc = PKCS11_CKR_GENERAL_ERROR;
519 		goto out;
520 	}
521 
522 	obj->attributes = attr;
523 	attr = NULL;
524 
525 	rc = PKCS11_CKR_OK;
526 
527 out:
528 	TEE_Free(attr);
529 	/* Close object only if it was open from this function */
530 	if (obj->attribs_hdl == TEE_HANDLE_NULL)
531 		TEE_CloseObject(hdl);
532 
533 	return rc;
534 }
535 
536 void release_persistent_object_attributes(struct pkcs11_object *obj)
537 {
538 	TEE_Free(obj->attributes);
539 	obj->attributes = NULL;
540 }
541 
542 enum pkcs11_rc update_persistent_object_attributes(struct pkcs11_object *obj)
543 {
544 	TEE_Result res = TEE_ERROR_GENERIC;
545 	TEE_ObjectHandle hdl = TEE_HANDLE_NULL;
546 	uint32_t tee_obj_flags = TEE_DATA_FLAG_ACCESS_WRITE;
547 	size_t size = 0;
548 
549 	assert(obj && obj->attributes);
550 
551 	res = TEE_OpenPersistentObject(TEE_STORAGE_PRIVATE,
552 				       obj->uuid, sizeof(*obj->uuid),
553 				       tee_obj_flags, &hdl);
554 	if (res) {
555 		EMSG("OpenPersistent failed %#"PRIx32, res);
556 		return tee2pkcs_error(res);
557 	}
558 
559 	size = sizeof(struct obj_attrs) + obj->attributes->attrs_size;
560 
561 	res = TEE_WriteObjectData(hdl, obj->attributes, size);
562 	if (res)
563 		goto out;
564 
565 	res = TEE_TruncateObjectData(hdl, size);
566 
567 out:
568 	TEE_CloseObject(hdl);
569 	return tee2pkcs_error(res);
570 }
571 
572 /*
573  * Return the token instance, either initialized from reset or initialized
574  * from the token persistent state if found.
575  */
576 struct ck_token *init_persistent_db(unsigned int token_id)
577 {
578 	struct ck_token *token = get_token(token_id);
579 	TEE_Result res = TEE_ERROR_GENERIC;
580 	TEE_ObjectHandle db_hdl = TEE_HANDLE_NULL;
581 	/* Copy persistent database: main db and object db */
582 	struct token_persistent_main *db_main = NULL;
583 	struct token_persistent_objs *db_objs = NULL;
584 	void *ptr = NULL;
585 
586 	if (!token)
587 		return NULL;
588 
589 	LIST_INIT(&token->object_list);
590 
591 	db_main = TEE_Malloc(sizeof(*db_main), TEE_MALLOC_FILL_ZERO);
592 	db_objs = TEE_Malloc(sizeof(*db_objs), TEE_MALLOC_FILL_ZERO);
593 	if (!db_main || !db_objs)
594 		goto error;
595 
596 	res = open_db_file(token, &db_hdl);
597 
598 	if (res == TEE_SUCCESS) {
599 		uint32_t size = 0;
600 		size_t idx = 0;
601 
602 		IMSG("PKCS11 token %u: load db", token_id);
603 
604 		size = sizeof(*db_main);
605 		res = TEE_ReadObjectData(db_hdl, db_main, size, &size);
606 		if (res || size != sizeof(*db_main))
607 			TEE_Panic(0);
608 
609 		size = sizeof(*db_objs);
610 		res = TEE_ReadObjectData(db_hdl, db_objs, size, &size);
611 		if (res || size != sizeof(*db_objs))
612 			TEE_Panic(0);
613 
614 		if (db_objs->count > 0) {
615 			size += db_objs->count * sizeof(TEE_UUID);
616 			ptr = TEE_Realloc(db_objs, size);
617 			if (!ptr)
618 				goto error;
619 
620 			db_objs = ptr;
621 			size -= sizeof(*db_objs);
622 			res = TEE_ReadObjectData(db_hdl, db_objs->uuids, size,
623 						 &size);
624 			if (res || size != (db_objs->count * sizeof(TEE_UUID)))
625 				TEE_Panic(0);
626 		}
627 
628 		for (idx = 0; idx < db_objs->count; idx++) {
629 			/* Create an empty object instance */
630 			struct pkcs11_object *obj = NULL;
631 			TEE_UUID *uuid = NULL;
632 
633 			uuid = TEE_Malloc(sizeof(TEE_UUID),
634 					  TEE_USER_MEM_HINT_NO_FILL_ZERO);
635 			if (!uuid)
636 				goto error;
637 
638 			TEE_MemMove(uuid, &db_objs->uuids[idx], sizeof(*uuid));
639 
640 			obj = create_token_object(NULL, uuid);
641 			if (!obj)
642 				TEE_Panic(0);
643 
644 			LIST_INSERT_HEAD(&token->object_list, obj, link);
645 		}
646 
647 	} else if (res == TEE_ERROR_ITEM_NOT_FOUND) {
648 		char file[PERSISTENT_OBJECT_ID_LEN] = { };
649 
650 		IMSG("PKCS11 token %u: init db", token_id);
651 
652 		TEE_MemFill(db_main, 0, sizeof(*db_main));
653 		TEE_MemFill(db_main->label, '*', sizeof(db_main->label));
654 
655 		db_main->flags = PKCS11_CKFT_SO_PIN_TO_BE_CHANGED |
656 				 PKCS11_CKFT_USER_PIN_TO_BE_CHANGED |
657 				 PKCS11_CKFT_RNG |
658 				 PKCS11_CKFT_DUAL_CRYPTO_OPERATIONS |
659 				 PKCS11_CKFT_LOGIN_REQUIRED;
660 
661 		res = get_db_file_name(token, file, sizeof(file));
662 		if (res)
663 			TEE_Panic(0);
664 
665 		/*
666 		 * Object stores persistent state + persistent object
667 		 * references.
668 		 */
669 		res = TEE_CreatePersistentObject(TEE_STORAGE_PRIVATE,
670 						 file, sizeof(file),
671 						 TEE_DATA_FLAG_ACCESS_READ |
672 						 TEE_DATA_FLAG_ACCESS_WRITE,
673 						 TEE_HANDLE_NULL,
674 						 db_main, sizeof(*db_main),
675 						 &db_hdl);
676 		if (res) {
677 			EMSG("Failed to create db: %#"PRIx32, res);
678 			goto error;
679 		}
680 
681 		res = TEE_TruncateObjectData(db_hdl, sizeof(*db_main) +
682 						     sizeof(*db_objs));
683 		if (res)
684 			TEE_Panic(0);
685 
686 		res = TEE_SeekObjectData(db_hdl, sizeof(*db_main),
687 					 TEE_DATA_SEEK_SET);
688 		if (res)
689 			TEE_Panic(0);
690 
691 		db_objs->count = 0;
692 		res = TEE_WriteObjectData(db_hdl, db_objs, sizeof(*db_objs));
693 		if (res)
694 			TEE_Panic(0);
695 
696 	} else {
697 		goto error;
698 	}
699 
700 	token->db_main = db_main;
701 	token->db_objs = db_objs;
702 	TEE_CloseObject(db_hdl);
703 
704 	return token;
705 
706 error:
707 	TEE_Free(db_main);
708 	TEE_Free(db_objs);
709 	if (db_hdl != TEE_HANDLE_NULL)
710 		TEE_CloseObject(db_hdl);
711 
712 	return NULL;
713 }
714