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
TSP_SetCapability(TSS_HCONTEXT tspContext,TSS_HTPM hTPM,TSS_HPOLICY hTPMPolicy,TPM_CAPABILITY_AREA tcsCapArea,UINT32 subCap,TSS_BOOL value)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
Transport_GetTPMCapability(TSS_HCONTEXT tspContext,TPM_CAPABILITY_AREA capArea,UINT32 subCapLen,BYTE * subCap,UINT32 * respLen,BYTE ** resp)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
Transport_SetCapability(TSS_HCONTEXT tspContext,TCPA_CAPABILITY_AREA capArea,UINT32 subCapSize,BYTE * subCap,UINT32 valueSize,BYTE * value,TPM_AUTH * ownerAuth)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