Home | History | Annotate | Line # | Download | only in tspi
      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 
     62 TSS_RESULT
     63 ps_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 
     78 TSS_RESULT
     79 ps_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 
     95 TSS_RESULT
     96 ps_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 
    111 TSS_RESULT
    112 ps_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 
    133 TSS_RESULT
    134 ps_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 
    148 TSS_RESULT
    149 ps_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 
    171 TSS_RESULT
    172 ps_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 
    193 TSS_RESULT
    194 ps_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 
    208 TSS_RESULT
    209 ps_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 
    224 TSS_RESULT
    225 ps_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 
    240 TSS_RESULT
    241 merge_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 
    266 TSS_RESULT
    267 merge_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
    293 TSS_RESULT
    294 load_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