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