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 "pkcs11_token.h" 14 #include "pkcs11_helpers.h" 15 16 void close_persistent_db(struct ck_token *token __unused) 17 { 18 } 19 20 static void init_pin_keys(struct ck_token *token, unsigned int uid) 21 { 22 TEE_Result res = TEE_ERROR_GENERIC; 23 unsigned int token_id = get_token_id(token); 24 TEE_ObjectHandle key_hdl = TEE_HANDLE_NULL; 25 char file[32] = { 0 }; 26 27 assert(token_id < 10 && uid < 10); 28 29 if (snprintf(file, 32, "token.db.%1d-pin%1d", token_id, uid) >= 32) 30 TEE_Panic(0); 31 32 res = TEE_OpenPersistentObject(TEE_STORAGE_PRIVATE, 33 file, sizeof(file), 0, &key_hdl); 34 35 if (res == TEE_ERROR_ITEM_NOT_FOUND) { 36 TEE_Attribute attr = { }; 37 TEE_ObjectHandle hdl = TEE_HANDLE_NULL; 38 uint8_t pin_key[16] = { 0 }; 39 40 TEE_MemFill(&attr, 0, sizeof(attr)); 41 42 TEE_GenerateRandom(pin_key, sizeof(pin_key)); 43 TEE_InitRefAttribute(&attr, TEE_ATTR_SECRET_VALUE, 44 pin_key, sizeof(pin_key)); 45 46 res = TEE_AllocateTransientObject(TEE_TYPE_AES, 128, &hdl); 47 if (res) 48 TEE_Panic(0); 49 50 res = TEE_PopulateTransientObject(hdl, &attr, 1); 51 if (res) 52 TEE_Panic(0); 53 54 res = TEE_CreatePersistentObject(TEE_STORAGE_PRIVATE, 55 file, sizeof(file), 0, hdl, 56 pin_key, sizeof(pin_key), 57 &key_hdl); 58 TEE_CloseObject(hdl); 59 60 if (res == TEE_SUCCESS) 61 DMSG("Token %u: PIN key created", token_id); 62 } 63 64 if (res) 65 TEE_Panic(res); 66 67 TEE_CloseObject(key_hdl); 68 } 69 70 /* 71 * Return the token instance, either initialized from reset or initialized 72 * from the token persistent state if found. 73 */ 74 struct ck_token *init_persistent_db(unsigned int token_id) 75 { 76 struct ck_token *token = get_token(token_id); 77 TEE_Result res = TEE_ERROR_GENERIC; 78 char db_file[32] = { 0 }; 79 TEE_ObjectHandle db_hdl = TEE_HANDLE_NULL; 80 struct token_persistent_main *db_main = NULL; 81 int n = 0; 82 83 if (!token) 84 return NULL; 85 86 for (n = 0; n < PKCS11_MAX_USERS; n++) 87 init_pin_keys(token, n); 88 89 db_main = TEE_Malloc(sizeof(*db_main), TEE_MALLOC_FILL_ZERO); 90 if (!db_main) 91 goto error; 92 93 if (snprintf(db_file, 32, "token.db.%1d", token_id) >= 32) 94 TEE_Panic(0); 95 96 res = TEE_OpenPersistentObject(TEE_STORAGE_PRIVATE, 97 db_file, sizeof(db_file), 98 TEE_DATA_FLAG_ACCESS_READ | 99 TEE_DATA_FLAG_ACCESS_WRITE, 100 &db_hdl); 101 if (res == TEE_SUCCESS) { 102 uint32_t size = 0; 103 104 IMSG("PKCS11 token %u: load db", token_id); 105 106 size = sizeof(*db_main); 107 res = TEE_ReadObjectData(db_hdl, db_main, size, &size); 108 if (res || size != sizeof(*db_main)) 109 TEE_Panic(0); 110 } else if (res == TEE_ERROR_ITEM_NOT_FOUND) { 111 IMSG("PKCS11 token %u: init db", token_id); 112 113 TEE_MemFill(db_main, 0, sizeof(*db_main)); 114 TEE_MemFill(db_main->label, '*', sizeof(db_main->label)); 115 116 db_main->flags = PKCS11_CKFT_SO_PIN_TO_BE_CHANGED | 117 PKCS11_CKFT_USER_PIN_TO_BE_CHANGED | 118 PKCS11_CKFT_RNG | 119 PKCS11_CKFT_DUAL_CRYPTO_OPERATIONS | 120 PKCS11_CKFT_LOGIN_REQUIRED; 121 122 res = TEE_CreatePersistentObject(TEE_STORAGE_PRIVATE, 123 db_file, sizeof(db_file), 124 TEE_DATA_FLAG_ACCESS_READ | 125 TEE_DATA_FLAG_ACCESS_WRITE, 126 TEE_HANDLE_NULL, 127 db_main, sizeof(*db_main), 128 &db_hdl); 129 if (res) { 130 EMSG("Failed to create db: %"PRIx32, res); 131 goto error; 132 } 133 } else { 134 goto error; 135 } 136 137 token->db_main = db_main; 138 TEE_CloseObject(db_hdl); 139 140 return token; 141 142 error: 143 TEE_Free(db_main); 144 if (db_hdl != TEE_HANDLE_NULL) 145 TEE_CloseObject(db_hdl); 146 147 return NULL; 148 } 149