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