1 2/* 3 * Licensed Materials - Property of IBM 4 * 5 * trousers - An open source TCG Software Stack 6 * 7 * (C) Copyright International Business Machines Corp. 2004-2006 8 * 9 */ 10 11#include <limits.h> 12#include <stdlib.h> 13#include <sys/types.h> 14#include <sys/file.h> 15#include <errno.h> 16#include <string.h> 17#include <unistd.h> 18#include <stdio.h> 19#include <limits.h> 20 21#include "trousers/tss.h" 22#include "trousers/trousers.h" 23#include "trousers_types.h" 24#include "spi_utils.h" 25#include "tcs_tsp.h" 26#include "tspps.h" 27#include "tsplog.h" 28#include "obj.h" 29 30/* 31 * tsp_ps.c 32 * 33 * Functions used to query the user persistent storage file. 34 * 35 * Since other apps may be altering the file, all operations must be atomic WRT the file and no 36 * cache will be kept, since another app could delete keys from the file out from under us. 37 * 38 * Atomicity is guaranteed for operations inbetween calls to get_file() and put_file(). 39 * 40 * A PS file will have the lifetime of the TSP context. For instance, this code will store hKeyA 41 * and hKeyB in the file "a": 42 * 43 * setenv("TSS_USER_PS_FILE=a"); 44 * Tspi_Context_Create(&hContext); 45 * Tspi_Context_RegisterKey(hKeyA); 46 * setenv("TSS_USER_PS_FILE=b"); 47 * Tspi_Context_RegisterKey(hKeyB); 48 * 49 * but this code will store hKeyA in file "a" and hKeyB in file "b": 50 * 51 * setenv("TSS_USER_PS_FILE=a"); 52 * Tspi_Context_Create(&hContext); 53 * Tspi_Context_RegisterKey(hKeyA); 54 * Tspi_Context_Close(hContext); 55 * 56 * setenv("TSS_USER_PS_FILE=b"); 57 * Tspi_Context_Create(&hContext); 58 * Tspi_Context_RegisterKey(hKeyB); 59 * 60 */ 61 62TSS_RESULT 63ps_get_registered_keys(TSS_UUID *uuid, TSS_UUID *tcs_uuid, UINT32 *size, TSS_KM_KEYINFO **keys) 64{ 65 int fd; 66 UINT32 result; 67 68 if ((result = get_file(&fd))) 69 return result; 70 71 result = psfile_get_registered_keys(fd, uuid, tcs_uuid, size, keys); 72 73 put_file(fd); 74 75 return result; 76} 77 78TSS_RESULT 79ps_get_registered_keys2(TSS_UUID *uuid, TSS_UUID *tcs_uuid, UINT32 *size, TSS_KM_KEYINFO2 **keys) 80{ 81 int fd; 82 UINT32 result; 83 84 if ((result = get_file(&fd))) 85 return result; 86 87 /* Sets the proper TSS_KM_KEYINFO2 fields according to the UUID type */ 88 result = psfile_get_registered_keys2(fd, uuid, tcs_uuid, size, keys); 89 90 put_file(fd); 91 92 return result; 93} 94 95TSS_RESULT 96ps_is_key_registered(TSS_UUID *uuid, TSS_BOOL *answer) 97{ 98 int fd; 99 TSS_RESULT result; 100 101 if ((result = get_file(&fd))) 102 return result; 103 104 result = psfile_is_key_registered(fd, uuid, answer); 105 106 put_file(fd); 107 108 return result; 109} 110 111TSS_RESULT 112ps_write_key(TSS_UUID *uuid, TSS_UUID *parent_uuid, UINT32 parent_ps, UINT32 blob_size, BYTE *blob) 113{ 114 int fd; 115 TSS_RESULT result; 116 UINT16 short_blob_size = (UINT16)blob_size; 117 118 if (blob_size > USHRT_MAX) { 119 LogError("Blob data being written to disk is too large(%u bytes)!", blob_size); 120 return TSPERR(TSS_E_INTERNAL_ERROR); 121 } 122 123 if ((result = get_file(&fd))) 124 return result; 125 126 result = psfile_write_key(fd, uuid, parent_uuid, parent_ps, blob, short_blob_size); 127 128 put_file(fd); 129 return result; 130} 131 132 133TSS_RESULT 134ps_remove_key(TSS_UUID *uuid) 135{ 136 int fd; 137 TSS_RESULT result; 138 139 if ((result = get_file(&fd))) 140 return result; 141 142 result = psfile_remove_key(fd, uuid); 143 144 put_file(fd); 145 return result; 146} 147 148TSS_RESULT 149ps_get_key_by_pub(TSS_HCONTEXT tspContext, UINT32 pub_size, BYTE *pub, TSS_HKEY *hKey) 150{ 151 int fd; 152 TSS_RESULT result = TSS_SUCCESS; 153 BYTE key[4096]; 154 TSS_UUID uuid; 155 156 if ((result = get_file(&fd))) 157 return result; 158 159 if ((result = psfile_get_key_by_pub(fd, &uuid, pub_size, pub, key))) { 160 put_file(fd); 161 return result; 162 } 163 164 put_file(fd); 165 166 result = obj_rsakey_add_by_key(tspContext, &uuid, key, TSS_OBJ_FLAG_USER_PS, hKey); 167 168 return result; 169} 170 171TSS_RESULT 172ps_get_key_by_uuid(TSS_HCONTEXT tspContext, TSS_UUID *uuid, TSS_HKEY *hKey) 173{ 174 int fd; 175 TSS_RESULT result = TSS_SUCCESS; 176 BYTE key[4096]; 177 178 if ((result = get_file(&fd))) 179 return result; 180 181 if ((result = psfile_get_key_by_uuid(fd, uuid, key))) { 182 put_file(fd); 183 return result; 184 } 185 186 put_file(fd); 187 188 result = obj_rsakey_add_by_key(tspContext, uuid, key, TSS_OBJ_FLAG_USER_PS, hKey); 189 190 return result; 191} 192 193TSS_RESULT 194ps_get_parent_uuid_by_uuid(TSS_UUID *uuid, TSS_UUID *parent_uuid) 195{ 196 int fd; 197 TSS_RESULT result; 198 199 if ((result = get_file(&fd))) 200 return result; 201 202 result = psfile_get_parent_uuid_by_uuid(fd, uuid, parent_uuid); 203 204 put_file(fd); 205 return result; 206} 207 208TSS_RESULT 209ps_get_parent_ps_type_by_uuid(TSS_UUID *uuid, UINT32 *type) 210{ 211 int fd; 212 TSS_RESULT result; 213 214 if ((result = get_file(&fd))) 215 return result; 216 217 result = psfile_get_parent_ps_type(fd, uuid, type); 218 219 put_file(fd); 220 221 return result; 222} 223 224TSS_RESULT 225ps_close() 226{ 227 TSS_RESULT result; 228 int fd; 229 230 if ((result = get_file(&fd))) 231 return result; 232 233 psfile_close(fd); 234 235 /* No need to call put_file() here, the file is closed */ 236 237 return TSS_SUCCESS; 238} 239 240TSS_RESULT 241merge_key_hierarchies(TSS_HCONTEXT tspContext, UINT32 tsp_size, TSS_KM_KEYINFO *tsp_hier, 242 UINT32 tcs_size, TSS_KM_KEYINFO *tcs_hier, UINT32 *merged_size, 243 TSS_KM_KEYINFO **merged_hier) 244{ 245 UINT32 i, j; 246 247 *merged_hier = malloc((tsp_size + tcs_size) * sizeof(TSS_KM_KEYINFO)); 248 if (*merged_hier == NULL) { 249 LogError("malloc of %zu bytes failed.", (tsp_size + tcs_size) * 250 sizeof(TSS_KM_KEYINFO)); 251 return TSPERR(TSS_E_OUTOFMEMORY); 252 } 253 254 for (i = 0; i < tsp_size; i++) 255 memcpy(&((*merged_hier)[i]), &tsp_hier[i], sizeof(TSS_KM_KEYINFO)); 256 257 for (j = 0; j < tcs_size; j++) 258 memcpy(&((*merged_hier)[i + j]), &tcs_hier[j], sizeof(TSS_KM_KEYINFO)); 259 260 *merged_size = i + j; 261 262 return TSS_SUCCESS; 263} 264 265 266TSS_RESULT 267merge_key_hierarchies2(TSS_HCONTEXT tspContext, UINT32 tsp_size, TSS_KM_KEYINFO2 *tsp_hier, 268 UINT32 tcs_size, TSS_KM_KEYINFO2 *tcs_hier, UINT32 *merged_size, 269 TSS_KM_KEYINFO2 **merged_hier) 270{ 271 UINT32 i, j; 272 273 *merged_hier = malloc((tsp_size + tcs_size) * sizeof(TSS_KM_KEYINFO2)); 274 if (*merged_hier == NULL) { 275 LogError("malloc of %zu bytes failed.", (tsp_size + tcs_size) * 276 sizeof(TSS_KM_KEYINFO2)); 277 return TSPERR(TSS_E_OUTOFMEMORY); 278 } 279 280 for (i = 0; i < tsp_size; i++) 281 memcpy(&((*merged_hier)[i]), &tsp_hier[i], sizeof(TSS_KM_KEYINFO2)); 282 283 for (j = 0; j < tcs_size; j++) 284 memcpy(&((*merged_hier)[i + j]), &tcs_hier[j], sizeof(TSS_KM_KEYINFO2)); 285 286 *merged_size = i + j; 287 288 return TSS_SUCCESS; 289} 290 291 292#if 0 293TSS_RESULT 294load_from_system_ps(TSS_HCONTEXT tspContext, TSS_UUID *uuid, TSS_HKEY *phKey) 295{ 296 TCS_KEY_HANDLE tcsKeyHandle; 297 TCS_LOADKEY_INFO info; 298 BYTE *keyBlob = NULL; 299 300 __tspi_memset(&info, 0, sizeof(TCS_LOADKEY_INFO)); 301 302 result = TCSP_LoadKeyByUUID(tspContext, uuidData, &info, &tcsKeyHandle); 303 304 if (TSS_ERROR_CODE(result) == TCS_E_KM_LOADFAILED) { 305 TSS_HKEY keyHandle; 306 TSS_HPOLICY hPolicy; 307 308 /* load failed, due to some key in the chain needing auth 309 * which doesn't yet exist at the TCS level. However, the 310 * auth may already be set in policies at the TSP level. 311 * To find out, get the key handle of the key requiring 312 * auth. First, look at the list of keys in memory. */ 313 if ((obj_rsakey_get_by_uuid(&info.parentKeyUUID, &keyHandle))) { 314 /* If that failed, look on disk, in User PS. */ 315 if (ps_get_key_by_uuid(tspContext, &info.parentKeyUUID, &keyHandle)) 316 return result; 317 } 318 319 if (obj_rsakey_get_policy(keyHandle, TSS_POLICY_USAGE, &hPolicy, NULL)) 320 return result; 321 322 if (secret_PerformAuth_OIAP(keyHandle, TPM_ORD_LoadKey, hPolicy, &info.paramDigest, 323 &info.authData)) 324 return result; 325 326 if ((result = TCSP_LoadKeyByUUID(tspContext, *uuid, &info, &tcsKeyHandle))) 327 return result; 328 } else if (result) 329 return result; 330 331 if ((result = TCS_GetRegisteredKeyBlob(tspContext, *uuid, &keyBlobSize, &keyBlob))) 332 return result; 333 334 if ((result = obj_rsakey_add_by_key(tspContext, uuid, keyBlob, TSS_OBJ_FLAG_SYSTEM_PS, 335 phKey))) { 336 free(keyBlob); 337 return result; 338 } 339 340 result = obj_rsakey_set_tcs_handle(*phKey, tcsKeyHandle); 341 342 free(keyBlob); 343 344 return result; 345} 346#endif 347 348