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