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