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