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