xref: /optee_os/ta/pkcs11/src/persistent_token.c (revision ea36ae9b4a2f188d4d2ebf2be3e40262a6e98d05)
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 	size_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)
290 {
291 	if (!token)
292 		return;
293 
294 	TEE_Free(token->db_main);
295 	token->db_main = NULL;
296 
297 	TEE_Free(token->db_objs);
298 	token->db_objs = NULL;
299 }
300 
301 static int get_persistent_obj_idx(struct ck_token *token, TEE_UUID *uuid)
302 {
303 	size_t i = 0;
304 
305 	if (!uuid)
306 		return -1;
307 
308 	for (i = 0; i < token->db_objs->count; i++)
309 		if (!TEE_MemCompare(token->db_objs->uuids + i,
310 				    uuid, sizeof(TEE_UUID)))
311 			return i;
312 
313 	return -1;
314 }
315 
316 /* UUID for persistent object */
317 enum pkcs11_rc create_object_uuid(struct ck_token *token,
318 				  struct pkcs11_object *obj)
319 {
320 	assert(!obj->uuid);
321 
322 	obj->uuid = TEE_Malloc(sizeof(TEE_UUID),
323 			       TEE_USER_MEM_HINT_NO_FILL_ZERO);
324 	if (!obj->uuid)
325 		return PKCS11_CKR_DEVICE_MEMORY;
326 
327 	obj->token = token;
328 
329 	do {
330 		TEE_GenerateRandom(obj->uuid, sizeof(TEE_UUID));
331 	} while (get_persistent_obj_idx(token, obj->uuid) >= 0);
332 
333 	return PKCS11_CKR_OK;
334 }
335 
336 void destroy_object_uuid(struct ck_token *token __maybe_unused,
337 			 struct pkcs11_object *obj)
338 {
339 	assert(get_persistent_obj_idx(token, obj->uuid) < 0);
340 
341 	TEE_Free(obj->uuid);
342 	obj->uuid = NULL;
343 }
344 
345 enum pkcs11_rc get_persistent_objects_list(struct ck_token *token,
346 					   TEE_UUID *array, size_t *size)
347 {
348 	size_t out_size = *size;
349 
350 	*size = token->db_objs->count * sizeof(TEE_UUID);
351 
352 	if (out_size < *size)
353 		return PKCS11_CKR_BUFFER_TOO_SMALL;
354 
355 	if (array)
356 		TEE_MemMove(array, token->db_objs->uuids, *size);
357 
358 	return PKCS11_CKR_OK;
359 }
360 
361 enum pkcs11_rc unregister_persistent_object(struct ck_token *token,
362 					    TEE_UUID *uuid)
363 {
364 	TEE_ObjectHandle db_hdl = TEE_HANDLE_NULL;
365 	struct token_persistent_objs *ptr = NULL;
366 	TEE_Result res = TEE_ERROR_GENERIC;
367 	int count = 0;
368 	int idx = 0;
369 
370 	if (!uuid)
371 		return PKCS11_CKR_OK;
372 
373 	idx = get_persistent_obj_idx(token, uuid);
374 	if (idx < 0) {
375 		DMSG("Cannot unregister an invalid persistent object");
376 		return PKCS11_RV_NOT_FOUND;
377 	}
378 
379 	ptr = TEE_Malloc(sizeof(struct token_persistent_objs) +
380 			 ((token->db_objs->count - 1) * sizeof(TEE_UUID)),
381 			 TEE_USER_MEM_HINT_NO_FILL_ZERO);
382 	if (!ptr)
383 		return PKCS11_CKR_DEVICE_MEMORY;
384 
385 	res = open_db_file(token, &db_hdl);
386 	if (res)
387 		goto out;
388 
389 	res = TEE_SeekObjectData(db_hdl, sizeof(struct token_persistent_main),
390 				 TEE_DATA_SEEK_SET);
391 	if (res) {
392 		DMSG("Failed to read database");
393 		goto out;
394 	}
395 
396 	TEE_MemMove(ptr, token->db_objs,
397 		    sizeof(struct token_persistent_objs) +
398 		    idx * sizeof(TEE_UUID));
399 
400 	ptr->count--;
401 	count = ptr->count - idx;
402 
403 	TEE_MemMove(&ptr->uuids[idx],
404 		    &token->db_objs->uuids[idx + 1],
405 		    count * sizeof(TEE_UUID));
406 
407 	res = TEE_WriteObjectData(db_hdl, ptr,
408 				  sizeof(struct token_persistent_objs) +
409 				  ptr->count * sizeof(TEE_UUID));
410 	if (res)
411 		DMSG("Failed to update database");
412 	TEE_Free(token->db_objs);
413 	token->db_objs = ptr;
414 	ptr = NULL;
415 
416 out:
417 	TEE_CloseObject(db_hdl);
418 	TEE_Free(ptr);
419 
420 	return tee2pkcs_error(res);
421 }
422 
423 enum pkcs11_rc register_persistent_object(struct ck_token *token,
424 					  TEE_UUID *uuid)
425 {
426 	TEE_ObjectHandle db_hdl = TEE_HANDLE_NULL;
427 	TEE_Result res = TEE_ERROR_GENERIC;
428 	void *ptr = NULL;
429 	size_t size = 0;
430 	int count = 0;
431 
432 	if (get_persistent_obj_idx(token, uuid) >= 0)
433 		TEE_Panic(0);
434 
435 	count = token->db_objs->count;
436 	ptr = TEE_Realloc(token->db_objs,
437 			  sizeof(struct token_persistent_objs) +
438 			  ((count + 1) * sizeof(TEE_UUID)));
439 	if (!ptr)
440 		return PKCS11_CKR_DEVICE_MEMORY;
441 
442 	token->db_objs = ptr;
443 	TEE_MemMove(token->db_objs->uuids + count, uuid, sizeof(TEE_UUID));
444 
445 	size = sizeof(struct token_persistent_main) +
446 	       sizeof(struct token_persistent_objs) +
447 	       count * sizeof(TEE_UUID);
448 
449 	res = open_db_file(token, &db_hdl);
450 	if (res)
451 		goto out;
452 
453 	res = TEE_TruncateObjectData(db_hdl, size + sizeof(TEE_UUID));
454 	if (res)
455 		goto out;
456 
457 	res = TEE_SeekObjectData(db_hdl, sizeof(struct token_persistent_main),
458 				 TEE_DATA_SEEK_SET);
459 	if (res)
460 		goto out;
461 
462 	token->db_objs->count++;
463 
464 	res = TEE_WriteObjectData(db_hdl, token->db_objs,
465 				  sizeof(struct token_persistent_objs) +
466 				  token->db_objs->count * sizeof(TEE_UUID));
467 	if (res)
468 		token->db_objs->count--;
469 
470 out:
471 	TEE_CloseObject(db_hdl);
472 
473 	return tee2pkcs_error(res);
474 }
475 
476 enum pkcs11_rc load_persistent_object_attributes(struct pkcs11_object *obj)
477 {
478 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
479 	TEE_Result res = TEE_ERROR_GENERIC;
480 	TEE_ObjectHandle hdl = obj->attribs_hdl;
481 	TEE_ObjectInfo info = { };
482 	struct obj_attrs *attr = NULL;
483 	size_t read_bytes = 0;
484 
485 	if (obj->attributes)
486 		return PKCS11_CKR_OK;
487 
488 	if (hdl == TEE_HANDLE_NULL) {
489 		res = TEE_OpenPersistentObject(TEE_STORAGE_PRIVATE,
490 					       obj->uuid, sizeof(*obj->uuid),
491 					       TEE_DATA_FLAG_ACCESS_READ, &hdl);
492 		if (res) {
493 			EMSG("OpenPersistent failed %#"PRIx32, res);
494 			return tee2pkcs_error(res);
495 		}
496 	}
497 
498 	TEE_MemFill(&info, 0, sizeof(info));
499 	res = TEE_GetObjectInfo1(hdl, &info);
500 	if (res) {
501 		EMSG("GetObjectInfo failed %#"PRIx32, res);
502 		rc = tee2pkcs_error(res);
503 		goto out;
504 	}
505 
506 	attr = TEE_Malloc(info.dataSize, TEE_MALLOC_FILL_ZERO);
507 	if (!attr) {
508 		rc = PKCS11_CKR_DEVICE_MEMORY;
509 		goto out;
510 	}
511 
512 	res = TEE_ReadObjectData(hdl, attr, info.dataSize, &read_bytes);
513 	if (!res) {
514 		res = TEE_SeekObjectData(hdl, 0, TEE_DATA_SEEK_SET);
515 		if (res)
516 			EMSG("Seek to 0 failed %#"PRIx32, res);
517 	}
518 
519 	if (res) {
520 		rc = tee2pkcs_error(res);
521 		EMSG("Read %zu bytes, failed %#"PRIx32,
522 		     read_bytes, res);
523 		goto out;
524 	}
525 	if (read_bytes != info.dataSize) {
526 		EMSG("Read %zu bytes, expected %zu",
527 		     read_bytes, info.dataSize);
528 		rc = PKCS11_CKR_GENERAL_ERROR;
529 		goto out;
530 	}
531 
532 	obj->attributes = attr;
533 	attr = NULL;
534 
535 	rc = PKCS11_CKR_OK;
536 
537 out:
538 	TEE_Free(attr);
539 	/* Close object only if it was open from this function */
540 	if (obj->attribs_hdl == TEE_HANDLE_NULL)
541 		TEE_CloseObject(hdl);
542 
543 	return rc;
544 }
545 
546 void release_persistent_object_attributes(struct pkcs11_object *obj)
547 {
548 	TEE_Free(obj->attributes);
549 	obj->attributes = NULL;
550 }
551 
552 enum pkcs11_rc update_persistent_object_attributes(struct pkcs11_object *obj)
553 {
554 	TEE_Result res = TEE_ERROR_GENERIC;
555 	TEE_ObjectHandle hdl = TEE_HANDLE_NULL;
556 	uint32_t tee_obj_flags = TEE_DATA_FLAG_ACCESS_WRITE;
557 	size_t size = 0;
558 
559 	assert(obj && obj->attributes);
560 
561 	res = TEE_OpenPersistentObject(TEE_STORAGE_PRIVATE,
562 				       obj->uuid, sizeof(*obj->uuid),
563 				       tee_obj_flags, &hdl);
564 	if (res) {
565 		EMSG("OpenPersistent failed %#"PRIx32, res);
566 		return tee2pkcs_error(res);
567 	}
568 
569 	size = sizeof(struct obj_attrs) + obj->attributes->attrs_size;
570 
571 	res = TEE_WriteObjectData(hdl, obj->attributes, size);
572 	if (res)
573 		goto out;
574 
575 	res = TEE_TruncateObjectData(hdl, size);
576 
577 out:
578 	TEE_CloseObject(hdl);
579 	return tee2pkcs_error(res);
580 }
581 
582 /*
583  * Return the token instance, either initialized from reset or initialized
584  * from the token persistent state if found.
585  */
586 struct ck_token *init_persistent_db(unsigned int token_id)
587 {
588 	struct ck_token *token = get_token(token_id);
589 	TEE_Result res = TEE_ERROR_GENERIC;
590 	TEE_ObjectHandle db_hdl = TEE_HANDLE_NULL;
591 	/* Copy persistent database: main db and object db */
592 	struct token_persistent_main *db_main = NULL;
593 	struct token_persistent_objs *db_objs = NULL;
594 	void *ptr = NULL;
595 	void *initial_data = NULL;
596 	uint32_t initial_data_size = 0;
597 
598 	if (!token)
599 		return NULL;
600 
601 	LIST_INIT(&token->object_list);
602 
603 	db_main = TEE_Malloc(sizeof(*db_main), TEE_MALLOC_FILL_ZERO);
604 	db_objs = TEE_Malloc(sizeof(*db_objs), TEE_MALLOC_FILL_ZERO);
605 	if (!db_main || !db_objs)
606 		goto error;
607 
608 	res = open_db_file(token, &db_hdl);
609 
610 	if (res == TEE_SUCCESS) {
611 		size_t size = 0;
612 		size_t idx = 0;
613 
614 		IMSG("PKCS11 token %u: load db", token_id);
615 
616 		size = sizeof(*db_main);
617 		res = TEE_ReadObjectData(db_hdl, db_main, size, &size);
618 		if (res || size != sizeof(*db_main))
619 			TEE_Panic(0);
620 
621 		size = sizeof(*db_objs);
622 		res = TEE_ReadObjectData(db_hdl, db_objs, size, &size);
623 		if (res || size != sizeof(*db_objs))
624 			TEE_Panic(0);
625 
626 		if (db_objs->count > 0) {
627 			size += db_objs->count * sizeof(TEE_UUID);
628 			ptr = TEE_Realloc(db_objs, size);
629 			if (!ptr)
630 				goto error;
631 
632 			db_objs = ptr;
633 			size -= sizeof(*db_objs);
634 			res = TEE_ReadObjectData(db_hdl, db_objs->uuids, size,
635 						 &size);
636 			if (res || size != (db_objs->count * sizeof(TEE_UUID)))
637 				TEE_Panic(0);
638 		}
639 
640 		for (idx = 0; idx < db_objs->count; idx++) {
641 			/* Create an empty object instance */
642 			struct pkcs11_object *obj = NULL;
643 			TEE_UUID *uuid = NULL;
644 
645 			uuid = TEE_Malloc(sizeof(TEE_UUID),
646 					  TEE_USER_MEM_HINT_NO_FILL_ZERO);
647 			if (!uuid)
648 				goto error;
649 
650 			TEE_MemMove(uuid, &db_objs->uuids[idx], sizeof(*uuid));
651 
652 			obj = create_token_object(NULL, uuid, token);
653 			if (!obj)
654 				TEE_Panic(0);
655 
656 			LIST_INSERT_HEAD(&token->object_list, obj, link);
657 		}
658 
659 	} else if (res == TEE_ERROR_ITEM_NOT_FOUND) {
660 		char file[PERSISTENT_OBJECT_ID_LEN] = { };
661 
662 		IMSG("PKCS11 token %u: init db", token_id);
663 
664 		TEE_MemFill(db_main, 0, sizeof(*db_main));
665 		TEE_MemFill(db_main->label, '*', sizeof(db_main->label));
666 
667 		db_main->flags = PKCS11_CKFT_SO_PIN_TO_BE_CHANGED |
668 				 PKCS11_CKFT_USER_PIN_TO_BE_CHANGED |
669 				 PKCS11_CKFT_RNG |
670 				 PKCS11_CKFT_LOGIN_REQUIRED;
671 
672 		res = get_db_file_name(token, file, sizeof(file));
673 		if (res)
674 			TEE_Panic(0);
675 
676 		/*
677 		 * Object stores persistent state + persistent object
678 		 * references.
679 		 *
680 		 * Allocate the initial_data buffer to encompass the data from
681 		 * both db_main and db_objs. Since the initial data for the
682 		 * objects will be zeroed out upon creation, there’s no need
683 		 * to copy it from db_objs.
684 		 */
685 		initial_data_size = sizeof(*db_main) + sizeof(*db_objs);
686 		initial_data = TEE_Malloc(initial_data_size,
687 					  TEE_MALLOC_FILL_ZERO);
688 		if (!initial_data) {
689 			EMSG("Failed to allocate initial_data buffer");
690 			goto error;
691 		}
692 		TEE_MemMove(initial_data, db_main, sizeof(*db_main));
693 		res = TEE_CreatePersistentObject(TEE_STORAGE_PRIVATE,
694 						 file, sizeof(file),
695 						 TEE_DATA_FLAG_ACCESS_READ |
696 						 TEE_DATA_FLAG_ACCESS_WRITE,
697 						 TEE_HANDLE_NULL,
698 						 initial_data,
699 						 initial_data_size,
700 						 &db_hdl);
701 		TEE_Free(initial_data);
702 		if (res) {
703 			EMSG("Failed to create db: %#"PRIx32, res);
704 			goto error;
705 		}
706 
707 	} else {
708 		goto error;
709 	}
710 
711 	token->db_main = db_main;
712 	token->db_objs = db_objs;
713 	TEE_CloseObject(db_hdl);
714 
715 	return token;
716 
717 error:
718 	TEE_Free(db_main);
719 	TEE_Free(db_objs);
720 	if (db_hdl != TEE_HANDLE_NULL)
721 		TEE_CloseObject(db_hdl);
722 
723 	return NULL;
724 }
725