1c84ccd0aSEtienne Carriere // SPDX-License-Identifier: BSD-2-Clause 2c84ccd0aSEtienne Carriere /* 3c84ccd0aSEtienne Carriere * Copyright (c) 2018-2020, Linaro Limited 4c84ccd0aSEtienne Carriere */ 5c84ccd0aSEtienne Carriere 6c84ccd0aSEtienne Carriere #include <assert.h> 7c84ccd0aSEtienne Carriere #include <pkcs11_ta.h> 8c84ccd0aSEtienne Carriere #include <string.h> 9c84ccd0aSEtienne Carriere #include <string_ext.h> 10c84ccd0aSEtienne Carriere #include <tee_internal_api_extensions.h> 11c84ccd0aSEtienne Carriere #include <util.h> 12c84ccd0aSEtienne Carriere 13c84ccd0aSEtienne Carriere #include "pkcs11_token.h" 14c84ccd0aSEtienne Carriere #include "pkcs11_helpers.h" 15c84ccd0aSEtienne Carriere 1660659a86SEtienne Carriere #define PERSISTENT_OBJECT_ID_LEN 32 1760659a86SEtienne Carriere 1860659a86SEtienne Carriere /* 1960659a86SEtienne Carriere * Token persistent objects 20*334316feSJens Wiklander * 21*334316feSJens Wiklander * The persistent objects are each identified by a UUID. 22*334316feSJens Wiklander * The persistent object database stores the list of the UUIDs registered. For 23*334316feSJens Wiklander * each it is expected that a file of ID "UUID" is stored in the TA secure 24*334316feSJens Wiklander * storage. 2560659a86SEtienne Carriere */ 2660659a86SEtienne Carriere static TEE_Result get_db_file_name(struct ck_token *token, 2760659a86SEtienne Carriere char *name, size_t size) 28c84ccd0aSEtienne Carriere { 2960659a86SEtienne Carriere int n = snprintf(name, size, "token.db.%u", get_token_id(token)); 3060659a86SEtienne Carriere 3160659a86SEtienne Carriere if (n < 0 || (size_t)n >= size) 3260659a86SEtienne Carriere return TEE_ERROR_SECURITY; 3360659a86SEtienne Carriere else 3460659a86SEtienne Carriere return TEE_SUCCESS; 3560659a86SEtienne Carriere } 3660659a86SEtienne Carriere 3760659a86SEtienne Carriere static TEE_Result open_db_file(struct ck_token *token, 3860659a86SEtienne Carriere TEE_ObjectHandle *out_hdl) 3960659a86SEtienne Carriere { 4060659a86SEtienne Carriere char file[PERSISTENT_OBJECT_ID_LEN] = { }; 4160659a86SEtienne Carriere TEE_Result res = TEE_ERROR_GENERIC; 4260659a86SEtienne Carriere 4360659a86SEtienne Carriere res = get_db_file_name(token, file, sizeof(file)); 4460659a86SEtienne Carriere if (res) 4560659a86SEtienne Carriere return res; 4660659a86SEtienne Carriere 4760659a86SEtienne Carriere return TEE_OpenPersistentObject(TEE_STORAGE_PRIVATE, file, sizeof(file), 4860659a86SEtienne Carriere TEE_DATA_FLAG_ACCESS_READ | 4960659a86SEtienne Carriere TEE_DATA_FLAG_ACCESS_WRITE, 5060659a86SEtienne Carriere out_hdl); 5160659a86SEtienne Carriere } 5260659a86SEtienne Carriere 53e86828f4SJens Wiklander void update_persistent_db(struct ck_token *token) 54e86828f4SJens Wiklander { 55e86828f4SJens Wiklander TEE_Result res = TEE_ERROR_GENERIC; 56e86828f4SJens Wiklander TEE_ObjectHandle db_hdl = TEE_HANDLE_NULL; 57e86828f4SJens Wiklander 58e86828f4SJens Wiklander res = open_db_file(token, &db_hdl); 59e86828f4SJens Wiklander if (res) { 60e86828f4SJens Wiklander EMSG("Failed to open token persistent db: %#"PRIx32, res); 61e86828f4SJens Wiklander TEE_Panic(0); 62e86828f4SJens Wiklander } 63e86828f4SJens Wiklander res = TEE_WriteObjectData(db_hdl, token->db_main, 64e86828f4SJens Wiklander sizeof(*token->db_main)); 65e86828f4SJens Wiklander if (res) { 66e86828f4SJens Wiklander EMSG("Failed to write to token persistent db: %#"PRIx32, res); 67e86828f4SJens Wiklander TEE_Panic(0); 68e86828f4SJens Wiklander } 69e86828f4SJens Wiklander 70e86828f4SJens Wiklander TEE_CloseObject(db_hdl); 71e86828f4SJens Wiklander } 72e86828f4SJens Wiklander 73bef8bc68SJens Wiklander static enum pkcs11_rc do_hash(uint32_t user, const uint8_t *pin, 74bef8bc68SJens Wiklander size_t pin_size, uint32_t salt, 75bef8bc68SJens Wiklander uint8_t hash[TEE_MAX_HASH_SIZE]) 76bef8bc68SJens Wiklander { 77bef8bc68SJens Wiklander TEE_Result res = TEE_SUCCESS; 78bef8bc68SJens Wiklander TEE_OperationHandle oh = TEE_HANDLE_NULL; 79bef8bc68SJens Wiklander uint32_t sz = TEE_MAX_HASH_SIZE; 80bef8bc68SJens Wiklander 81bef8bc68SJens Wiklander res = TEE_AllocateOperation(&oh, TEE_ALG_SHA256, TEE_MODE_DIGEST, 0); 82bef8bc68SJens Wiklander if (res) 83bef8bc68SJens Wiklander return tee2pkcs_error(res); 84bef8bc68SJens Wiklander 85bef8bc68SJens Wiklander TEE_DigestUpdate(oh, &user, sizeof(user)); 86bef8bc68SJens Wiklander TEE_DigestUpdate(oh, &salt, sizeof(salt)); 87bef8bc68SJens Wiklander res = TEE_DigestDoFinal(oh, pin, pin_size, hash, &sz); 88bef8bc68SJens Wiklander TEE_FreeOperation(oh); 89bef8bc68SJens Wiklander 90bef8bc68SJens Wiklander if (res) 91bef8bc68SJens Wiklander return PKCS11_CKR_GENERAL_ERROR; 92bef8bc68SJens Wiklander 93bef8bc68SJens Wiklander memset(hash + sz, 0, TEE_MAX_HASH_SIZE - sz); 94bef8bc68SJens Wiklander return PKCS11_CKR_OK; 95bef8bc68SJens Wiklander } 96bef8bc68SJens Wiklander 97bef8bc68SJens Wiklander enum pkcs11_rc hash_pin(enum pkcs11_user_type user, const uint8_t *pin, 98bef8bc68SJens Wiklander size_t pin_size, uint32_t *salt, 99bef8bc68SJens Wiklander uint8_t hash[TEE_MAX_HASH_SIZE]) 100bef8bc68SJens Wiklander { 101bef8bc68SJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 102bef8bc68SJens Wiklander uint32_t s = 0; 103bef8bc68SJens Wiklander 104bef8bc68SJens Wiklander TEE_GenerateRandom(&s, sizeof(s)); 105bef8bc68SJens Wiklander if (!s) 106bef8bc68SJens Wiklander s++; 107bef8bc68SJens Wiklander 108bef8bc68SJens Wiklander rc = do_hash(user, pin, pin_size, s, hash); 109bef8bc68SJens Wiklander if (!rc) 110bef8bc68SJens Wiklander *salt = s; 111bef8bc68SJens Wiklander return rc; 112bef8bc68SJens Wiklander } 113bef8bc68SJens Wiklander 114bef8bc68SJens Wiklander enum pkcs11_rc verify_pin(enum pkcs11_user_type user, const uint8_t *pin, 115bef8bc68SJens Wiklander size_t pin_size, uint32_t salt, 116bef8bc68SJens Wiklander const uint8_t hash[TEE_MAX_HASH_SIZE]) 117bef8bc68SJens Wiklander { 118bef8bc68SJens Wiklander uint8_t tmp_hash[TEE_MAX_HASH_SIZE] = { 0 }; 119bef8bc68SJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 120bef8bc68SJens Wiklander 121bef8bc68SJens Wiklander rc = do_hash(user, pin, pin_size, salt, tmp_hash); 122bef8bc68SJens Wiklander if (rc) 123bef8bc68SJens Wiklander return rc; 124bef8bc68SJens Wiklander 125bef8bc68SJens Wiklander if (buf_compare_ct(tmp_hash, hash, TEE_MAX_HASH_SIZE)) 126bef8bc68SJens Wiklander rc = PKCS11_CKR_PIN_INCORRECT; 127bef8bc68SJens Wiklander 128bef8bc68SJens Wiklander return rc; 129bef8bc68SJens Wiklander } 130bef8bc68SJens Wiklander 131c84ccd0aSEtienne Carriere /* 13260659a86SEtienne Carriere * Release resources relate to persistent database 13360659a86SEtienne Carriere */ 13460659a86SEtienne Carriere void close_persistent_db(struct ck_token *token __unused) 13560659a86SEtienne Carriere { 13660659a86SEtienne Carriere } 13760659a86SEtienne Carriere 138*334316feSJens Wiklander static int get_persistent_obj_idx(struct ck_token *token, TEE_UUID *uuid) 139*334316feSJens Wiklander { 140*334316feSJens Wiklander size_t i = 0; 141*334316feSJens Wiklander 142*334316feSJens Wiklander if (!uuid) 143*334316feSJens Wiklander return -1; 144*334316feSJens Wiklander 145*334316feSJens Wiklander for (i = 0; i < token->db_objs->count; i++) 146*334316feSJens Wiklander if (!TEE_MemCompare(token->db_objs->uuids + i, 147*334316feSJens Wiklander uuid, sizeof(TEE_UUID))) 148*334316feSJens Wiklander return i; 149*334316feSJens Wiklander 150*334316feSJens Wiklander return -1; 151*334316feSJens Wiklander } 152*334316feSJens Wiklander 153*334316feSJens Wiklander /* UUID for persistent object */ 154*334316feSJens Wiklander enum pkcs11_rc create_object_uuid(struct ck_token *token, 155*334316feSJens Wiklander struct pkcs11_object *obj) 156*334316feSJens Wiklander { 157*334316feSJens Wiklander assert(!obj->uuid); 158*334316feSJens Wiklander 159*334316feSJens Wiklander obj->uuid = TEE_Malloc(sizeof(TEE_UUID), 160*334316feSJens Wiklander TEE_USER_MEM_HINT_NO_FILL_ZERO); 161*334316feSJens Wiklander if (!obj->uuid) 162*334316feSJens Wiklander return PKCS11_CKR_DEVICE_MEMORY; 163*334316feSJens Wiklander 164*334316feSJens Wiklander do { 165*334316feSJens Wiklander TEE_GenerateRandom(obj->uuid, sizeof(TEE_UUID)); 166*334316feSJens Wiklander } while (get_persistent_obj_idx(token, obj->uuid) >= 0); 167*334316feSJens Wiklander 168*334316feSJens Wiklander return PKCS11_CKR_OK; 169*334316feSJens Wiklander } 170*334316feSJens Wiklander 171*334316feSJens Wiklander void destroy_object_uuid(struct ck_token *token __maybe_unused, 172*334316feSJens Wiklander struct pkcs11_object *obj) 173*334316feSJens Wiklander { 174*334316feSJens Wiklander assert(get_persistent_obj_idx(token, obj->uuid) < 0); 175*334316feSJens Wiklander 176*334316feSJens Wiklander TEE_Free(obj->uuid); 177*334316feSJens Wiklander obj->uuid = NULL; 178*334316feSJens Wiklander } 179*334316feSJens Wiklander 180*334316feSJens Wiklander enum pkcs11_rc get_persistent_objects_list(struct ck_token *token, 181*334316feSJens Wiklander TEE_UUID *array, size_t *size) 182*334316feSJens Wiklander { 183*334316feSJens Wiklander size_t out_size = *size; 184*334316feSJens Wiklander 185*334316feSJens Wiklander *size = token->db_objs->count * sizeof(TEE_UUID); 186*334316feSJens Wiklander 187*334316feSJens Wiklander if (out_size < *size) 188*334316feSJens Wiklander return PKCS11_CKR_BUFFER_TOO_SMALL; 189*334316feSJens Wiklander 190*334316feSJens Wiklander if (array) 191*334316feSJens Wiklander TEE_MemMove(array, token->db_objs->uuids, *size); 192*334316feSJens Wiklander 193*334316feSJens Wiklander return PKCS11_CKR_OK; 194*334316feSJens Wiklander } 195*334316feSJens Wiklander 196*334316feSJens Wiklander enum pkcs11_rc unregister_persistent_object(struct ck_token *token, 197*334316feSJens Wiklander TEE_UUID *uuid) 198*334316feSJens Wiklander { 199*334316feSJens Wiklander TEE_ObjectHandle db_hdl = TEE_HANDLE_NULL; 200*334316feSJens Wiklander struct token_persistent_objs *ptr = NULL; 201*334316feSJens Wiklander TEE_Result res = TEE_ERROR_GENERIC; 202*334316feSJens Wiklander int count = 0; 203*334316feSJens Wiklander int idx = 0; 204*334316feSJens Wiklander 205*334316feSJens Wiklander if (!uuid) 206*334316feSJens Wiklander return PKCS11_CKR_OK; 207*334316feSJens Wiklander 208*334316feSJens Wiklander idx = get_persistent_obj_idx(token, uuid); 209*334316feSJens Wiklander if (idx < 0) { 210*334316feSJens Wiklander DMSG("Cannot unregister an invalid persistent object"); 211*334316feSJens Wiklander return PKCS11_RV_NOT_FOUND; 212*334316feSJens Wiklander } 213*334316feSJens Wiklander 214*334316feSJens Wiklander ptr = TEE_Malloc(sizeof(struct token_persistent_objs) + 215*334316feSJens Wiklander ((token->db_objs->count - 1) * sizeof(TEE_UUID)), 216*334316feSJens Wiklander TEE_USER_MEM_HINT_NO_FILL_ZERO); 217*334316feSJens Wiklander if (!ptr) 218*334316feSJens Wiklander return PKCS11_CKR_DEVICE_MEMORY; 219*334316feSJens Wiklander 220*334316feSJens Wiklander res = open_db_file(token, &db_hdl); 221*334316feSJens Wiklander if (res) 222*334316feSJens Wiklander goto out; 223*334316feSJens Wiklander 224*334316feSJens Wiklander res = TEE_SeekObjectData(db_hdl, sizeof(struct token_persistent_main), 225*334316feSJens Wiklander TEE_DATA_SEEK_SET); 226*334316feSJens Wiklander if (res) { 227*334316feSJens Wiklander DMSG("Failed to read database"); 228*334316feSJens Wiklander goto out; 229*334316feSJens Wiklander } 230*334316feSJens Wiklander 231*334316feSJens Wiklander TEE_MemMove(ptr, token->db_objs, 232*334316feSJens Wiklander sizeof(struct token_persistent_objs) + 233*334316feSJens Wiklander idx * sizeof(TEE_UUID)); 234*334316feSJens Wiklander 235*334316feSJens Wiklander ptr->count--; 236*334316feSJens Wiklander count = ptr->count - idx; 237*334316feSJens Wiklander 238*334316feSJens Wiklander TEE_MemMove(&ptr->uuids[idx], 239*334316feSJens Wiklander &token->db_objs->uuids[idx + 1], 240*334316feSJens Wiklander count * sizeof(TEE_UUID)); 241*334316feSJens Wiklander 242*334316feSJens Wiklander res = TEE_WriteObjectData(db_hdl, ptr, 243*334316feSJens Wiklander sizeof(struct token_persistent_objs) + 244*334316feSJens Wiklander ptr->count * sizeof(TEE_UUID)); 245*334316feSJens Wiklander if (res) 246*334316feSJens Wiklander DMSG("Failed to update database"); 247*334316feSJens Wiklander TEE_Free(token->db_objs); 248*334316feSJens Wiklander token->db_objs = ptr; 249*334316feSJens Wiklander ptr = NULL; 250*334316feSJens Wiklander 251*334316feSJens Wiklander out: 252*334316feSJens Wiklander TEE_CloseObject(db_hdl); 253*334316feSJens Wiklander TEE_Free(ptr); 254*334316feSJens Wiklander 255*334316feSJens Wiklander return tee2pkcs_error(res); 256*334316feSJens Wiklander } 257*334316feSJens Wiklander 258*334316feSJens Wiklander enum pkcs11_rc register_persistent_object(struct ck_token *token, 259*334316feSJens Wiklander TEE_UUID *uuid) 260*334316feSJens Wiklander { 261*334316feSJens Wiklander TEE_ObjectHandle db_hdl = TEE_HANDLE_NULL; 262*334316feSJens Wiklander TEE_Result res = TEE_ERROR_GENERIC; 263*334316feSJens Wiklander void *ptr = NULL; 264*334316feSJens Wiklander size_t size = 0; 265*334316feSJens Wiklander int count = 0; 266*334316feSJens Wiklander 267*334316feSJens Wiklander if (get_persistent_obj_idx(token, uuid) >= 0) 268*334316feSJens Wiklander TEE_Panic(0); 269*334316feSJens Wiklander 270*334316feSJens Wiklander count = token->db_objs->count; 271*334316feSJens Wiklander ptr = TEE_Realloc(token->db_objs, 272*334316feSJens Wiklander sizeof(struct token_persistent_objs) + 273*334316feSJens Wiklander ((count + 1) * sizeof(TEE_UUID))); 274*334316feSJens Wiklander if (!ptr) 275*334316feSJens Wiklander return PKCS11_CKR_DEVICE_MEMORY; 276*334316feSJens Wiklander 277*334316feSJens Wiklander token->db_objs = ptr; 278*334316feSJens Wiklander TEE_MemMove(token->db_objs->uuids + count, uuid, sizeof(TEE_UUID)); 279*334316feSJens Wiklander 280*334316feSJens Wiklander size = sizeof(struct token_persistent_main) + 281*334316feSJens Wiklander sizeof(struct token_persistent_objs) + 282*334316feSJens Wiklander count * sizeof(TEE_UUID); 283*334316feSJens Wiklander 284*334316feSJens Wiklander res = open_db_file(token, &db_hdl); 285*334316feSJens Wiklander if (res) 286*334316feSJens Wiklander goto out; 287*334316feSJens Wiklander 288*334316feSJens Wiklander res = TEE_TruncateObjectData(db_hdl, size + sizeof(TEE_UUID)); 289*334316feSJens Wiklander if (res) 290*334316feSJens Wiklander goto out; 291*334316feSJens Wiklander 292*334316feSJens Wiklander res = TEE_SeekObjectData(db_hdl, sizeof(struct token_persistent_main), 293*334316feSJens Wiklander TEE_DATA_SEEK_SET); 294*334316feSJens Wiklander if (res) 295*334316feSJens Wiklander goto out; 296*334316feSJens Wiklander 297*334316feSJens Wiklander token->db_objs->count++; 298*334316feSJens Wiklander 299*334316feSJens Wiklander res = TEE_WriteObjectData(db_hdl, token->db_objs, 300*334316feSJens Wiklander sizeof(struct token_persistent_objs) + 301*334316feSJens Wiklander token->db_objs->count * sizeof(TEE_UUID)); 302*334316feSJens Wiklander if (res) 303*334316feSJens Wiklander token->db_objs->count--; 304*334316feSJens Wiklander 305*334316feSJens Wiklander out: 306*334316feSJens Wiklander TEE_CloseObject(db_hdl); 307*334316feSJens Wiklander 308*334316feSJens Wiklander return tee2pkcs_error(res); 309*334316feSJens Wiklander } 310*334316feSJens Wiklander 31160659a86SEtienne Carriere /* 312c84ccd0aSEtienne Carriere * Return the token instance, either initialized from reset or initialized 313c84ccd0aSEtienne Carriere * from the token persistent state if found. 314c84ccd0aSEtienne Carriere */ 315c84ccd0aSEtienne Carriere struct ck_token *init_persistent_db(unsigned int token_id) 316c84ccd0aSEtienne Carriere { 317c84ccd0aSEtienne Carriere struct ck_token *token = get_token(token_id); 318c84ccd0aSEtienne Carriere TEE_Result res = TEE_ERROR_GENERIC; 319c84ccd0aSEtienne Carriere TEE_ObjectHandle db_hdl = TEE_HANDLE_NULL; 32060659a86SEtienne Carriere /* Copy persistent database: main db and object db */ 321c84ccd0aSEtienne Carriere struct token_persistent_main *db_main = NULL; 322*334316feSJens Wiklander struct token_persistent_objs *db_objs = NULL; 323*334316feSJens Wiklander void *ptr = NULL; 324c84ccd0aSEtienne Carriere 325c84ccd0aSEtienne Carriere if (!token) 326c84ccd0aSEtienne Carriere return NULL; 327c84ccd0aSEtienne Carriere 328*334316feSJens Wiklander LIST_INIT(&token->object_list); 329*334316feSJens Wiklander 330c84ccd0aSEtienne Carriere db_main = TEE_Malloc(sizeof(*db_main), TEE_MALLOC_FILL_ZERO); 331*334316feSJens Wiklander db_objs = TEE_Malloc(sizeof(*db_objs), TEE_MALLOC_FILL_ZERO); 332*334316feSJens Wiklander if (!db_main || !db_objs) 333c84ccd0aSEtienne Carriere goto error; 334c84ccd0aSEtienne Carriere 33560659a86SEtienne Carriere res = open_db_file(token, &db_hdl); 336c84ccd0aSEtienne Carriere 337c84ccd0aSEtienne Carriere if (res == TEE_SUCCESS) { 338c84ccd0aSEtienne Carriere uint32_t size = 0; 339*334316feSJens Wiklander size_t idx = 0; 340c84ccd0aSEtienne Carriere 341c84ccd0aSEtienne Carriere IMSG("PKCS11 token %u: load db", token_id); 342c84ccd0aSEtienne Carriere 343c84ccd0aSEtienne Carriere size = sizeof(*db_main); 344c84ccd0aSEtienne Carriere res = TEE_ReadObjectData(db_hdl, db_main, size, &size); 345c84ccd0aSEtienne Carriere if (res || size != sizeof(*db_main)) 346c84ccd0aSEtienne Carriere TEE_Panic(0); 347*334316feSJens Wiklander 348*334316feSJens Wiklander size = sizeof(*db_objs); 349*334316feSJens Wiklander res = TEE_ReadObjectData(db_hdl, db_objs, size, &size); 350*334316feSJens Wiklander if (res || size != sizeof(*db_objs)) 351*334316feSJens Wiklander TEE_Panic(0); 352*334316feSJens Wiklander 353*334316feSJens Wiklander size += db_objs->count * sizeof(TEE_UUID); 354*334316feSJens Wiklander ptr = TEE_Realloc(db_objs, size); 355*334316feSJens Wiklander if (!ptr) 356*334316feSJens Wiklander goto error; 357*334316feSJens Wiklander 358*334316feSJens Wiklander db_objs = ptr; 359*334316feSJens Wiklander size -= sizeof(struct token_persistent_objs); 360*334316feSJens Wiklander res = TEE_ReadObjectData(db_hdl, db_objs->uuids, size, &size); 361*334316feSJens Wiklander if (res || size != (db_objs->count * sizeof(TEE_UUID))) 362*334316feSJens Wiklander TEE_Panic(0); 363*334316feSJens Wiklander 364*334316feSJens Wiklander for (idx = 0; idx < db_objs->count; idx++) { 365*334316feSJens Wiklander /* Create an empty object instance */ 366*334316feSJens Wiklander struct pkcs11_object *obj = NULL; 367*334316feSJens Wiklander TEE_UUID *uuid = NULL; 368*334316feSJens Wiklander 369*334316feSJens Wiklander uuid = TEE_Malloc(sizeof(TEE_UUID), 370*334316feSJens Wiklander TEE_USER_MEM_HINT_NO_FILL_ZERO); 371*334316feSJens Wiklander if (!uuid) 372*334316feSJens Wiklander goto error; 373*334316feSJens Wiklander 374*334316feSJens Wiklander TEE_MemMove(uuid, &db_objs->uuids[idx], sizeof(*uuid)); 375*334316feSJens Wiklander 376*334316feSJens Wiklander obj = create_token_object(NULL, uuid); 377*334316feSJens Wiklander if (!obj) 378*334316feSJens Wiklander TEE_Panic(0); 379*334316feSJens Wiklander 380*334316feSJens Wiklander LIST_INSERT_HEAD(&token->object_list, obj, link); 381*334316feSJens Wiklander } 382*334316feSJens Wiklander 383c84ccd0aSEtienne Carriere } else if (res == TEE_ERROR_ITEM_NOT_FOUND) { 38460659a86SEtienne Carriere char file[PERSISTENT_OBJECT_ID_LEN] = { }; 38560659a86SEtienne Carriere 386c84ccd0aSEtienne Carriere IMSG("PKCS11 token %u: init db", token_id); 387c84ccd0aSEtienne Carriere 388c84ccd0aSEtienne Carriere TEE_MemFill(db_main, 0, sizeof(*db_main)); 389c84ccd0aSEtienne Carriere TEE_MemFill(db_main->label, '*', sizeof(db_main->label)); 390c84ccd0aSEtienne Carriere 391c84ccd0aSEtienne Carriere db_main->flags = PKCS11_CKFT_SO_PIN_TO_BE_CHANGED | 392c84ccd0aSEtienne Carriere PKCS11_CKFT_USER_PIN_TO_BE_CHANGED | 393c84ccd0aSEtienne Carriere PKCS11_CKFT_RNG | 394c84ccd0aSEtienne Carriere PKCS11_CKFT_DUAL_CRYPTO_OPERATIONS | 395c84ccd0aSEtienne Carriere PKCS11_CKFT_LOGIN_REQUIRED; 396c84ccd0aSEtienne Carriere 39760659a86SEtienne Carriere res = get_db_file_name(token, file, sizeof(file)); 39860659a86SEtienne Carriere if (res) 39960659a86SEtienne Carriere TEE_Panic(0); 40060659a86SEtienne Carriere 401*334316feSJens Wiklander /* 402*334316feSJens Wiklander * Object stores persistent state + persistent object 403*334316feSJens Wiklander * references. 404*334316feSJens Wiklander */ 405c84ccd0aSEtienne Carriere res = TEE_CreatePersistentObject(TEE_STORAGE_PRIVATE, 40660659a86SEtienne Carriere file, sizeof(file), 407c84ccd0aSEtienne Carriere TEE_DATA_FLAG_ACCESS_READ | 408c84ccd0aSEtienne Carriere TEE_DATA_FLAG_ACCESS_WRITE, 409c84ccd0aSEtienne Carriere TEE_HANDLE_NULL, 410c84ccd0aSEtienne Carriere db_main, sizeof(*db_main), 411c84ccd0aSEtienne Carriere &db_hdl); 412c84ccd0aSEtienne Carriere if (res) { 413c84ccd0aSEtienne Carriere EMSG("Failed to create db: %"PRIx32, res); 414c84ccd0aSEtienne Carriere goto error; 415c84ccd0aSEtienne Carriere } 416*334316feSJens Wiklander 417*334316feSJens Wiklander res = TEE_TruncateObjectData(db_hdl, sizeof(*db_main) + 418*334316feSJens Wiklander sizeof(*db_objs)); 419*334316feSJens Wiklander if (res) 420*334316feSJens Wiklander TEE_Panic(0); 421*334316feSJens Wiklander 422*334316feSJens Wiklander res = TEE_SeekObjectData(db_hdl, sizeof(*db_main), 423*334316feSJens Wiklander TEE_DATA_SEEK_SET); 424*334316feSJens Wiklander if (res) 425*334316feSJens Wiklander TEE_Panic(0); 426*334316feSJens Wiklander 427*334316feSJens Wiklander db_objs->count = 0; 428*334316feSJens Wiklander res = TEE_WriteObjectData(db_hdl, db_objs, sizeof(*db_objs)); 429*334316feSJens Wiklander if (res) 430*334316feSJens Wiklander TEE_Panic(0); 431*334316feSJens Wiklander 432c84ccd0aSEtienne Carriere } else { 433c84ccd0aSEtienne Carriere goto error; 434c84ccd0aSEtienne Carriere } 435c84ccd0aSEtienne Carriere 436c84ccd0aSEtienne Carriere token->db_main = db_main; 437*334316feSJens Wiklander token->db_objs = db_objs; 438c84ccd0aSEtienne Carriere TEE_CloseObject(db_hdl); 439c84ccd0aSEtienne Carriere 440c84ccd0aSEtienne Carriere return token; 441c84ccd0aSEtienne Carriere 442c84ccd0aSEtienne Carriere error: 443c84ccd0aSEtienne Carriere TEE_Free(db_main); 444*334316feSJens Wiklander TEE_Free(db_objs); 445c84ccd0aSEtienne Carriere if (db_hdl != TEE_HANDLE_NULL) 446c84ccd0aSEtienne Carriere TEE_CloseObject(db_hdl); 447c84ccd0aSEtienne Carriere 448c84ccd0aSEtienne Carriere return NULL; 449c84ccd0aSEtienne Carriere } 450