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 */ 29TSS_RESULT 30TSP_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 73TSS_RESULT 74Transport_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 128TSS_RESULT 129Transport_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