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