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. 2006
      8  *
      9  */
     10 
     11 #include <stdlib.h>
     12 #include <stdio.h>
     13 #include <string.h>
     14 #include <inttypes.h>
     15 
     16 #include "trousers/tss.h"
     17 #include "trousers/trousers.h"
     18 #include "trousers_types.h"
     19 #include "spi_utils.h"
     20 #include "capabilities.h"
     21 #include "tsplog.h"
     22 #include "obj.h"
     23 
     24 
     25 /*
     26  * This function provides a funnel through which all the TCSP_SetCapability requests can be
     27  * sent.  This will keep the owner auth code from being duplicated around the TSP.
     28  */
     29 TSS_RESULT
     30 TSP_SetCapability(TSS_HCONTEXT tspContext,
     31 		  TSS_HTPM hTPM,
     32 		  TSS_HPOLICY hTPMPolicy,
     33 		  TPM_CAPABILITY_AREA tcsCapArea,
     34 		  UINT32 subCap,
     35 		  TSS_BOOL value)
     36 {
     37 	TSS_RESULT result;
     38 	Trspi_HashCtx hashCtx;
     39 	TPM_DIGEST digest;
     40 	TPM_AUTH auth;
     41 
     42 	subCap = endian32(subCap);
     43 
     44 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
     45 	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_SetCapability);
     46 	result |= Trspi_Hash_UINT32(&hashCtx, tcsCapArea);
     47 	result |= Trspi_Hash_UINT32(&hashCtx, (UINT32)sizeof(UINT32));
     48 	result |= Trspi_HashUpdate(&hashCtx, (UINT32)sizeof(UINT32), (BYTE *)&subCap);
     49 	result |= Trspi_Hash_UINT32(&hashCtx, (UINT32)sizeof(TSS_BOOL));
     50 	result |= Trspi_Hash_BOOL(&hashCtx, value);
     51 	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
     52 		return result;
     53 
     54 	if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_SetCapability, hTPMPolicy, FALSE,
     55 					      &digest, &auth)))
     56 		return result;
     57 
     58 	if ((result = TCS_API(tspContext)->SetCapability(tspContext, tcsCapArea, sizeof(UINT32),
     59 							 (BYTE *)&subCap, sizeof(TSS_BOOL),
     60 							 (BYTE *)&value, &auth)))
     61 		return result;
     62 
     63 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
     64 	result |= Trspi_Hash_UINT32(&hashCtx, result);
     65 	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_SetCapability);
     66 	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
     67 		return result;
     68 
     69 	return obj_policy_validate_auth_oiap(hTPMPolicy, &digest, &auth);
     70 }
     71 
     72 #ifdef TSS_BUILD_TRANSPORT
     73 TSS_RESULT
     74 Transport_GetTPMCapability(TSS_HCONTEXT        tspContext,	/* in */
     75 			   TPM_CAPABILITY_AREA capArea,	/* in */
     76 			   UINT32              subCapLen,	/* in */
     77 			   BYTE*               subCap,	/* in */
     78 			   UINT32*             respLen,	/* out */
     79 			   BYTE**              resp)	/* out */
     80 {
     81 	TSS_RESULT result;
     82 	UINT32 decLen = 0, dataLen;
     83 	BYTE *dec = NULL;
     84 	UINT64 offset;
     85 	TCS_HANDLE handlesLen = 0;
     86 	BYTE *data;
     87 
     88 	if ((result = obj_context_transport_init(tspContext)))
     89 		return result;
     90 
     91 	LogDebugFn("Executing in a transport session");
     92 
     93 	dataLen = (2 * sizeof(UINT32)) + subCapLen;
     94 	if ((data = malloc(dataLen)) == NULL) {
     95 		LogError("malloc of %u bytes failed", dataLen);
     96 		return TSPERR(TSS_E_OUTOFMEMORY);
     97 	}
     98 
     99 	offset = 0;
    100 	Trspi_LoadBlob_UINT32(&offset, capArea, data);
    101 	Trspi_LoadBlob_UINT32(&offset, subCapLen, data);
    102 	Trspi_LoadBlob(&offset, subCapLen, data, subCap);
    103 
    104 	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_GetCapability, dataLen,
    105 						    data, NULL, &handlesLen, NULL, NULL, NULL,
    106 						    &decLen, &dec))) {
    107 		free(data);
    108 		return result;
    109 	}
    110 	free(data);
    111 
    112 	offset = 0;
    113 	Trspi_UnloadBlob_UINT32(&offset, respLen, dec);
    114 
    115 	if ((*resp = malloc(*respLen)) == NULL) {
    116 		free(dec);
    117 		LogError("malloc of %u bytes failed", *respLen);
    118 		return TSPERR(TSS_E_OUTOFMEMORY);
    119 	}
    120 
    121 	Trspi_UnloadBlob(&offset, *respLen, dec, *resp);
    122 	free(dec);
    123 
    124 	return result;
    125 
    126 }
    127 
    128 TSS_RESULT
    129 Transport_SetCapability(TSS_HCONTEXT tspContext,	/* in */
    130 			TCPA_CAPABILITY_AREA capArea,	/* in */
    131 			UINT32 subCapSize,	/* in */
    132 			BYTE * subCap,	/* in */
    133 			UINT32 valueSize,	/* in */
    134 			BYTE * value,	/* in */
    135 			TPM_AUTH *ownerAuth) /* in, out */
    136 {
    137 	TSS_RESULT result;
    138 	UINT32 dataLen;
    139 	UINT64 offset;
    140 	TCS_HANDLE handlesLen = 0;
    141 	BYTE *data;
    142 
    143 	if ((result = obj_context_transport_init(tspContext)))
    144 		return result;
    145 
    146 	LogDebugFn("Executing in a transport session");
    147 
    148 	dataLen = (3 * sizeof(UINT32)) + subCapSize + valueSize;
    149 	if ((data = malloc(dataLen)) == NULL) {
    150 		LogError("malloc of %u bytes failed", dataLen);
    151 		return TSPERR(TSS_E_OUTOFMEMORY);
    152 	}
    153 
    154 	offset = 0;
    155 	Trspi_LoadBlob_UINT32(&offset, capArea, data);
    156 	Trspi_LoadBlob_UINT32(&offset, subCapSize, data);
    157 	Trspi_LoadBlob(&offset, subCapSize, data, subCap);
    158 	Trspi_LoadBlob_UINT32(&offset, valueSize, data);
    159 	Trspi_LoadBlob(&offset, valueSize, data, value);
    160 
    161 	result = obj_context_transport_execute(tspContext, TPM_ORD_SetCapability, dataLen, data,
    162 					       NULL, &handlesLen, NULL, NULL, NULL, NULL, NULL);
    163 
    164 	free(data);
    165 	return result;
    166 }
    167 #endif
    168