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. 2007
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 #ifdef TSS_BUILD_TRANSPORT
26 TSS_RESULT
Transport_NV_DefineOrReleaseSpace(TSS_HCONTEXT tspContext,UINT32 cPubInfoSize,BYTE * pPubInfo,TCPA_ENCAUTH encAuth,TPM_AUTH * pAuth)27 Transport_NV_DefineOrReleaseSpace(TSS_HCONTEXT tspContext,	/* in */
28 				  UINT32 cPubInfoSize,	/* in */
29 				  BYTE* pPubInfo,		/* in */
30 				  TCPA_ENCAUTH encAuth,	/* in */
31 				  TPM_AUTH* pAuth)		/* in, out */
32 {
33 	TSS_RESULT result;
34 	UINT32 dataLen;
35 	UINT64 offset;
36 	TCS_HANDLE handlesLen = 0;
37 	BYTE *data;
38 
39 	if ((result = obj_context_transport_init(tspContext)))
40 		return result;
41 
42 	LogDebugFn("Executing in a transport session");
43 
44 	dataLen = sizeof(TCPA_ENCAUTH) + cPubInfoSize;
45 	if ((data = malloc(dataLen)) == NULL) {
46 		LogError("malloc of %u bytes failed", dataLen);
47 		return TSPERR(TSS_E_OUTOFMEMORY);
48 	}
49 
50 	offset = 0;
51 	Trspi_LoadBlob(&offset, cPubInfoSize, data, pPubInfo);
52 	Trspi_LoadBlob(&offset, TPM_SHA1_160_HASH_LEN, data, encAuth.authdata);
53 
54 	result = obj_context_transport_execute(tspContext, TPM_ORD_NV_DefineSpace, dataLen, data,
55 					       NULL, &handlesLen, NULL, pAuth, NULL, NULL, NULL);
56 	free(data);
57 
58 	return result;
59 }
60 
61 TSS_RESULT
Transport_NV_WriteValue(TSS_HCONTEXT tspContext,TSS_NV_INDEX hNVStore,UINT32 offset,UINT32 ulDataLength,BYTE * rgbDataToWrite,TPM_AUTH * privAuth)62 Transport_NV_WriteValue(TSS_HCONTEXT tspContext,	/* in */
63 			TSS_NV_INDEX hNVStore,	/* in */
64 			UINT32 offset,		/* in */
65 			UINT32 ulDataLength,		/* in */
66 			BYTE* rgbDataToWrite,	/* in */
67 			TPM_AUTH* privAuth)		/* in, out */
68 {
69 	TSS_RESULT result;
70 	UINT32 dataLen;
71 	UINT64 offset64;
72 	TCS_HANDLE handlesLen = 0;
73 	BYTE *data;
74 
75 	if ((result = obj_context_transport_init(tspContext)))
76 		return result;
77 
78 	LogDebugFn("Executing in a transport session");
79 
80 	dataLen = sizeof(TSS_NV_INDEX) + (2 * sizeof(UINT32)) + ulDataLength;
81 	if ((data = malloc(dataLen)) == NULL) {
82 		LogError("malloc of %u bytes failed", dataLen);
83 		return TSPERR(TSS_E_OUTOFMEMORY);
84 	}
85 
86 	offset64 = 0;
87 	Trspi_LoadBlob_UINT32(&offset64, hNVStore, data);
88 	Trspi_LoadBlob_UINT32(&offset64, offset, data);
89 	Trspi_LoadBlob_UINT32(&offset64, ulDataLength, data);
90 	Trspi_LoadBlob(&offset64, ulDataLength, data, rgbDataToWrite);
91 
92 	result = obj_context_transport_execute(tspContext, TPM_ORD_NV_WriteValue, dataLen, data,
93 					       NULL, &handlesLen, NULL, privAuth, NULL, NULL, NULL);
94 	free(data);
95 
96 	return result;
97 }
98 
99 TSS_RESULT
Transport_NV_WriteValueAuth(TSS_HCONTEXT tspContext,TSS_NV_INDEX hNVStore,UINT32 offset,UINT32 ulDataLength,BYTE * rgbDataToWrite,TPM_AUTH * NVAuth)100 Transport_NV_WriteValueAuth(TSS_HCONTEXT tspContext,	/* in */
101 			    TSS_NV_INDEX hNVStore,		/* in */
102 			    UINT32 offset,			/* in */
103 			    UINT32 ulDataLength,		/* in */
104 			    BYTE* rgbDataToWrite,		/* in */
105 			    TPM_AUTH* NVAuth)		/* in, out */
106 {
107 	TSS_RESULT result;
108 	UINT32 dataLen;
109 	UINT64 offset64;
110 	TCS_HANDLE handlesLen = 0;
111 	BYTE *data;
112 
113 	if ((result = obj_context_transport_init(tspContext)))
114 		return result;
115 
116 	LogDebugFn("Executing in a transport session");
117 
118 	dataLen = sizeof(TSS_NV_INDEX) + (2 * sizeof(UINT32)) + ulDataLength;
119 	if ((data = malloc(dataLen)) == NULL) {
120 		LogError("malloc of %u bytes failed", dataLen);
121 		return TSPERR(TSS_E_OUTOFMEMORY);
122 	}
123 
124 	offset64 = 0;
125 	Trspi_LoadBlob_UINT32(&offset64, hNVStore, data);
126 	Trspi_LoadBlob_UINT32(&offset64, offset, data);
127 	Trspi_LoadBlob_UINT32(&offset64, ulDataLength, data);
128 	Trspi_LoadBlob(&offset64, ulDataLength, data, rgbDataToWrite);
129 
130 	result = obj_context_transport_execute(tspContext, TPM_ORD_NV_WriteValueAuth, dataLen, data,
131 					       NULL, &handlesLen, NULL, NVAuth, NULL, NULL, NULL);
132 	free(data);
133 
134 	return result;
135 }
136 
137 
138 TSS_RESULT
Transport_NV_ReadValue(TSS_HCONTEXT tspContext,TSS_NV_INDEX hNVStore,UINT32 offset,UINT32 * pulDataLength,TPM_AUTH * privAuth,BYTE ** rgbDataRead)139 Transport_NV_ReadValue(TSS_HCONTEXT tspContext,	/* in */
140 		       TSS_NV_INDEX hNVStore,	/* in */
141 		       UINT32 offset,		/* in */
142 		       UINT32* pulDataLength,	/* in, out */
143 		       TPM_AUTH* privAuth,		/* in, out */
144 		       BYTE** rgbDataRead)		/* out */
145 {
146 	TSS_RESULT result;
147 	UINT32 dataLen, decLen;
148 	UINT64 offset64;
149 	TCS_HANDLE handlesLen = 0;
150 	BYTE *data, *dec;
151 
152 	if ((result = obj_context_transport_init(tspContext)))
153 		return result;
154 
155 	LogDebugFn("Executing in a transport session");
156 
157 	dataLen = sizeof(TSS_NV_INDEX) + sizeof(UINT32) + *pulDataLength;
158 	if ((data = malloc(dataLen)) == NULL) {
159 		LogError("malloc of %u bytes failed", dataLen);
160 		return TSPERR(TSS_E_OUTOFMEMORY);
161 	}
162 
163 	offset64 = 0;
164 	Trspi_LoadBlob_UINT32(&offset64, hNVStore, data);
165 	Trspi_LoadBlob_UINT32(&offset64, offset, data);
166 	Trspi_LoadBlob_UINT32(&offset64, *pulDataLength, data);
167 
168 	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_NV_ReadValue, dataLen, data,
169 						    NULL, &handlesLen, NULL, privAuth, NULL,
170 						    &decLen, &dec))) {
171 		free(data);
172 		return result;
173 	}
174 	free(data);
175 
176 	offset64 = 0;
177 	Trspi_UnloadBlob_UINT32(&offset64, pulDataLength, dec);
178 
179 	if ((*rgbDataRead = malloc(*pulDataLength)) == NULL) {
180 		free(dec);
181 		LogError("malloc of %u bytes failed", *pulDataLength);
182 		*pulDataLength = 0;
183 		return TSPERR(TSS_E_OUTOFMEMORY);
184 	}
185 	Trspi_UnloadBlob(&offset64, *pulDataLength, dec, *rgbDataRead);
186 	free(dec);
187 
188 	return result;
189 }
190 
191 
192 TSS_RESULT
Transport_NV_ReadValueAuth(TSS_HCONTEXT tspContext,TSS_NV_INDEX hNVStore,UINT32 offset,UINT32 * pulDataLength,TPM_AUTH * NVAuth,BYTE ** rgbDataRead)193 Transport_NV_ReadValueAuth(TSS_HCONTEXT tspContext,	/* in */
194 			   TSS_NV_INDEX hNVStore,    /* in */
195 			   UINT32 offset,		/* in */
196 			   UINT32* pulDataLength,    /* in, out */
197 			   TPM_AUTH* NVAuth,		/* in, out */
198 			   BYTE** rgbDataRead)       /* out */
199 {
200 	TSS_RESULT result;
201 	UINT32 dataLen, decLen;
202 	UINT64 offset64;
203 	TCS_HANDLE handlesLen = 0;
204 	BYTE *data, *dec;
205 
206 	if ((result = obj_context_transport_init(tspContext)))
207 		return result;
208 
209 	LogDebugFn("Executing in a transport session");
210 
211 	dataLen = sizeof(TSS_NV_INDEX) + sizeof(UINT32) + *pulDataLength;
212 	if ((data = malloc(dataLen)) == NULL) {
213 		LogError("malloc of %u bytes failed", dataLen);
214 		return TSPERR(TSS_E_OUTOFMEMORY);
215 	}
216 
217 	offset64 = 0;
218 	Trspi_LoadBlob_UINT32(&offset64, hNVStore, data);
219 	Trspi_LoadBlob_UINT32(&offset64, offset, data);
220 	Trspi_LoadBlob_UINT32(&offset64, *pulDataLength, data);
221 
222 	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_NV_ReadValueAuth, dataLen,
223 						    data, NULL, &handlesLen, NULL, NVAuth, NULL,
224 						    &decLen, &dec))) {
225 		free(data);
226 		return result;
227 	}
228 	free(data);
229 
230 	offset64 = 0;
231 	Trspi_UnloadBlob_UINT32(&offset64, pulDataLength, dec);
232 
233 	if ((*rgbDataRead = malloc(*pulDataLength)) == NULL) {
234 		free(dec);
235 		LogError("malloc of %u bytes failed", *pulDataLength);
236 		*pulDataLength = 0;
237 		return TSPERR(TSS_E_OUTOFMEMORY);
238 	}
239 	Trspi_UnloadBlob(&offset64, *pulDataLength, dec, *rgbDataRead);
240 	free(dec);
241 
242 	return result;
243 }
244 
245 #endif
246