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-2007
      8  *
      9  */
     10 
     11 
     12 #include <stdlib.h>
     13 #include <string.h>
     14 
     15 #include "trousers/tss.h"
     16 #include "trousers/trousers.h"
     17 #include "trousers_types.h"
     18 #include "spi_utils.h"
     19 #include "capabilities.h"
     20 #include "tsplog.h"
     21 #include "obj.h"
     22 
     23 
     24 void
     25 free_key_refs(TSS_KEY *key)
     26 {
     27 	free(key->algorithmParms.parms);
     28 	key->algorithmParms.parms = NULL;
     29 	key->algorithmParms.parmSize = 0;
     30 
     31 	free(key->pubKey.key);
     32 	key->pubKey.key = NULL;
     33 	key->pubKey.keyLength = 0;
     34 
     35 	free(key->encData);
     36 	key->encData = NULL;
     37 	key->encSize = 0;
     38 
     39 	free(key->PCRInfo);
     40 	key->PCRInfo = NULL;
     41 	key->PCRInfoSize = 0;
     42 }
     43 
     44 void
     45 LoadBlob_TSS_KEY(UINT64 *offset, BYTE *blob, TSS_KEY *key)
     46 {
     47 	if (key->hdr.key12.tag == TPM_TAG_KEY12)
     48 		Trspi_LoadBlob_KEY12(offset, blob, (TPM_KEY12 *)key);
     49 	else
     50 		Trspi_LoadBlob_KEY(offset, blob, (TCPA_KEY *)key);
     51 }
     52 
     53 TSS_RESULT
     54 UnloadBlob_TSS_KEY(UINT64 *offset, BYTE *blob, TSS_KEY *key)
     55 {
     56 	UINT16 tag;
     57 	UINT64 keyOffset = *offset;
     58 	TSS_RESULT result;
     59 
     60 	Trspi_UnloadBlob_UINT16(&keyOffset, &tag, blob);
     61 	if (tag == TPM_TAG_KEY12)
     62 		result = Trspi_UnloadBlob_KEY12(offset, blob, (TPM_KEY12 *)key);
     63 	else
     64 		result = Trspi_UnloadBlob_KEY(offset, blob, (TCPA_KEY *)key);
     65 
     66 	return result;
     67 }
     68 
     69 TSS_RESULT
     70 Hash_TSS_KEY(Trspi_HashCtx *c, TSS_KEY *key)
     71 {
     72 	TSS_RESULT result;
     73 
     74 	if (key->hdr.key12.tag == TPM_TAG_KEY12)
     75 		result = Trspi_Hash_KEY12(c, (TPM_KEY12 *)key);
     76 	else
     77 		result = Trspi_Hash_KEY(c, (TCPA_KEY *)key);
     78 
     79 	return result;
     80 }
     81 
     82 void
     83 LoadBlob_TSS_PRIVKEY_DIGEST(UINT64 *offset, BYTE *blob, TSS_KEY *key)
     84 {
     85 	if (key->hdr.key12.tag == TPM_TAG_KEY12)
     86 		Trspi_LoadBlob_PRIVKEY_DIGEST12(offset, blob, (TPM_KEY12 *)key);
     87 	else
     88 		Trspi_LoadBlob_PRIVKEY_DIGEST(offset, blob, (TCPA_KEY *)key);
     89 }
     90 
     91 TSS_RESULT
     92 Hash_TSS_PRIVKEY_DIGEST(Trspi_HashCtx *c, TSS_KEY *key)
     93 {
     94 	TSS_RESULT result;
     95 
     96 	if (key->hdr.key12.tag == TPM_TAG_KEY12)
     97 		result = Trspi_Hash_PRIVKEY_DIGEST12(c, (TPM_KEY12 *)key);
     98 	else
     99 		result = Trspi_Hash_PRIVKEY_DIGEST(c, (TCPA_KEY *)key);
    100 
    101 	return result;
    102 }
    103 
    104 #ifdef TSS_BUILD_TRANSPORT
    105 TSS_RESULT
    106 Transport_EvictKey(TSS_HCONTEXT tspContext,
    107 		   TCS_KEY_HANDLE hKey)
    108 {
    109 	TSS_RESULT result;
    110 	UINT32 handlesLen;
    111 	TCS_HANDLE *handles, handle;
    112 	TPM_DIGEST pubKeyHash;
    113 	Trspi_HashCtx hashCtx;
    114 
    115 
    116 	if ((result = obj_context_transport_init(tspContext)))
    117 		return result;
    118 
    119 	LogDebugFn("Executing in a transport session");
    120 
    121 	if ((result = obj_tcskey_get_pubkeyhash(hKey, pubKeyHash.digest)))
    122 		return result;
    123 
    124 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
    125 	result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest);
    126 	if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest)))
    127 		return result;
    128 
    129 	handlesLen = 1;
    130 	handle = hKey;
    131 	handles = &handle;
    132 
    133 	result = obj_context_transport_execute(tspContext, TPM_ORD_EvictKey, 0, NULL, &pubKeyHash,
    134 					       &handlesLen, &handles, NULL, NULL, NULL, NULL);
    135 
    136 	return result;
    137 }
    138 
    139 TSS_RESULT
    140 Transport_GetPubKey(TSS_HCONTEXT tspContext,
    141 		    TCS_KEY_HANDLE hKey,
    142 		    TPM_AUTH *pAuth,
    143 		    UINT32 *pcPubKeySize,
    144 		    BYTE **prgbPubKey)
    145 {
    146 	TSS_RESULT result;
    147 	UINT32 handlesLen, decLen;
    148 	TCS_HANDLE *handles, handle;
    149 	BYTE *dec = NULL;
    150 	TPM_DIGEST pubKeyHash;
    151 	Trspi_HashCtx hashCtx;
    152 
    153 
    154 	if ((result = obj_context_transport_init(tspContext)))
    155 		return result;
    156 
    157 	LogDebugFn("Executing in a transport session");
    158 
    159 	if ((result = obj_tcskey_get_pubkeyhash(hKey, pubKeyHash.digest)))
    160 		return result;
    161 
    162 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
    163 	result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest);
    164 	if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest)))
    165 		return result;
    166 
    167 	handlesLen = 1;
    168 	handle = hKey;
    169 	handles = &handle;
    170 
    171 	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_GetPubKey, 0, NULL,
    172 						    &pubKeyHash, &handlesLen, &handles, pAuth, NULL,
    173 						    &decLen, &dec)))
    174 		return result;
    175 
    176 	*prgbPubKey = dec;
    177 	*pcPubKeySize = decLen;
    178 
    179 	return result;
    180 }
    181 
    182 TSS_RESULT
    183 Transport_CreateWrapKey(TSS_HCONTEXT tspContext,	/* in */
    184 			TCS_KEY_HANDLE hWrappingKey,	/* in */
    185 			TPM_ENCAUTH *KeyUsageAuth,	/* in */
    186 			TPM_ENCAUTH *KeyMigrationAuth,	/* in */
    187 			UINT32 keyInfoSize,		/* in */
    188 			BYTE * keyInfo,			/* in */
    189 			UINT32 * keyDataSize,		/* out */
    190 			BYTE ** keyData,		/* out */
    191 			TPM_AUTH * pAuth)		/* in, out */
    192 {
    193 	TSS_RESULT result;
    194 	UINT32 handlesLen, decLen;
    195 	TCS_HANDLE *handles, handle;
    196 	BYTE *dec = NULL;
    197 	TPM_DIGEST pubKeyHash;
    198 	Trspi_HashCtx hashCtx;
    199 	UINT64 offset;
    200 	BYTE *data;
    201 
    202 
    203 	if ((result = obj_context_transport_init(tspContext)))
    204 		return result;
    205 
    206 	LogDebugFn("Executing in a transport session");
    207 
    208 	if ((result = obj_tcskey_get_pubkeyhash(hWrappingKey, pubKeyHash.digest)))
    209 		return result;
    210 
    211 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
    212 	result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest);
    213 	if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest)))
    214 		return result;
    215 
    216 	handlesLen = 1;
    217 	handle = hWrappingKey;
    218 	handles = &handle;
    219 
    220 	if ((data = malloc(2 * sizeof(TPM_ENCAUTH) + keyInfoSize)) == NULL) {
    221 		LogError("malloc of %zd bytes failed", 2 * sizeof(TPM_ENCAUTH) + keyInfoSize);
    222 		return TSPERR(TSS_E_OUTOFMEMORY);
    223 	}
    224 
    225 	offset = 0;
    226 	Trspi_LoadBlob(&offset, sizeof(TPM_ENCAUTH), data, KeyUsageAuth->authdata);
    227 	Trspi_LoadBlob(&offset, sizeof(TPM_ENCAUTH), data, KeyMigrationAuth->authdata);
    228 	Trspi_LoadBlob(&offset, keyInfoSize, data, keyInfo);
    229 
    230 	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_CreateWrapKey,
    231 						    (2 * sizeof(TPM_ENCAUTH) + keyInfoSize), data,
    232 						    &pubKeyHash, &handlesLen, &handles, pAuth, NULL,
    233 						    &decLen, &dec)))
    234 		goto done;
    235 
    236 	*keyDataSize = decLen;
    237 	*keyData = dec;
    238 done:
    239 	free(data);
    240 
    241 	return result;
    242 }
    243 
    244 TSS_RESULT
    245 Transport_LoadKeyByBlob(TSS_HCONTEXT     tspContext,
    246 			TCS_KEY_HANDLE   hParentKey,
    247 			UINT32           ulBlobLength,
    248 			BYTE*            rgbBlobData,
    249 			TPM_AUTH*        pAuth,
    250 			TCS_KEY_HANDLE*  phKey,
    251 			TPM_KEY_HANDLE*  phSlot)
    252 {
    253 	TSS_RESULT result;
    254 	UINT32 handlesLen, decLen;
    255 	TCS_HANDLE *handles, handle;
    256 	BYTE *dec = NULL;
    257 	TPM_DIGEST pubKeyHash;
    258 	Trspi_HashCtx hashCtx;
    259 
    260 
    261 	if ((result = obj_context_transport_init(tspContext)))
    262 		return result;
    263 
    264 	LogDebugFn("Executing in a transport session");
    265 
    266 	if ((result = obj_tcskey_get_pubkeyhash(hParentKey, pubKeyHash.digest)))
    267 		return result;
    268 
    269 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
    270 	result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest);
    271 	if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest)))
    272 		return result;
    273 
    274 	handlesLen = 1;
    275 	handle = hParentKey;
    276 	handles = &handle;
    277 
    278 	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_LoadKey2, ulBlobLength,
    279 						    rgbBlobData, &pubKeyHash, &handlesLen,
    280 						    &handles, pAuth, NULL, &decLen, &dec)))
    281 		return result;
    282 
    283 	if (handlesLen == 1)
    284 		*phKey = *(TCS_KEY_HANDLE *)handles;
    285 	else
    286 		result = TSPERR(TSS_E_INTERNAL_ERROR);
    287 
    288 	free(dec);
    289 
    290 	return result;
    291 }
    292 
    293 /* This function both encrypts the handle of the pubkey being requested and requires the hash
    294  * of that pubkey for the transport log when logging is enabled. */
    295 TSS_RESULT
    296 Transport_OwnerReadInternalPub(TSS_HCONTEXT tspContext,   /* in */
    297 			       TCS_KEY_HANDLE hKey,           /* in */
    298 			       TPM_AUTH* pOwnerAuth,          /* in, out */
    299 			       UINT32* punPubKeySize, /* out */
    300 			       BYTE** ppbPubKeyData)          /* out */
    301 {
    302 	UINT64 offset;
    303 	TSS_RESULT result;
    304 	UINT32 handlesLen = 0, decLen;
    305 	TPM_DIGEST pubKeyHash;
    306 	Trspi_HashCtx hashCtx;
    307 	BYTE *dec = NULL, data[sizeof(TCS_KEY_HANDLE)];
    308 
    309 
    310 	if ((result = obj_context_transport_init(tspContext)))
    311 		return result;
    312 
    313 	LogDebugFn("Executing in a transport session");
    314 
    315 	if ((result = obj_tcskey_get_pubkeyhash(hKey, pubKeyHash.digest)))
    316 		return result;
    317 
    318 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
    319 	result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest);
    320 	if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest)))
    321 		return result;
    322 
    323 	offset = 0;
    324 	Trspi_LoadBlob_UINT32(&offset, hKey, data);
    325 
    326 	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_OwnerReadInternalPub,
    327 						    sizeof(data), data, &pubKeyHash, &handlesLen,
    328 						    NULL, pOwnerAuth, NULL, &decLen, &dec)))
    329 		return result;
    330 
    331 	*punPubKeySize = decLen;
    332 	*ppbPubKeyData = dec;
    333 
    334 	return result;
    335 }
    336 #endif
    337 
    338