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. 2004-2006
8  *
9  */
10 
11 #include <stdlib.h>
12 #include <stdio.h>
13 #include <syslog.h>
14 #include <string.h>
15 #include <netdb.h>
16 
17 #include "trousers/tss.h"
18 #include "trousers_types.h"
19 #include "tcs_tsp.h"
20 #include "tcs_utils.h"
21 #include "tcs_int_literals.h"
22 #include "capabilities.h"
23 #include "tcslog.h"
24 #include "tcsd_wrap.h"
25 #include "tcsd.h"
26 #include "tcs_utils.h"
27 #include "rpc_tcstp_tcs.h"
28 
29 
30 TSS_RESULT
tcs_wrap_GetPcrEvent(struct tcsd_thread_data * data)31 tcs_wrap_GetPcrEvent(struct tcsd_thread_data *data)
32 {
33           TCS_CONTEXT_HANDLE hContext;
34           TSS_PCR_EVENT *pEvent = NULL;
35           TSS_RESULT result;
36           UINT32 pcrIndex, number;
37           BYTE lengthOnly;
38 
39           if (getData(TCSD_PACKET_TYPE_UINT32, 0, &hContext, 0, &data->comm))
40                     return TCSERR(TSS_E_INTERNAL_ERROR);
41 
42           if ((result = ctx_verify_context(hContext)))
43                     goto done;
44 
45           LogDebugFn("thread %ld context %x", THREAD_ID, hContext);
46 
47           if (getData(TCSD_PACKET_TYPE_UINT32, 1, &pcrIndex, 0, &data->comm))
48                     return TCSERR(TSS_E_INTERNAL_ERROR);
49 
50           if (getData(TCSD_PACKET_TYPE_UINT32, 2, &number, 0, &data->comm))
51                     return TCSERR(TSS_E_INTERNAL_ERROR);
52 
53           if (getData(TCSD_PACKET_TYPE_BYTE, 3, &lengthOnly, 0, &data->comm))
54                     return TCSERR(TSS_E_INTERNAL_ERROR);
55 
56           if (lengthOnly)
57                     result = TCS_GetPcrEvent_Internal(hContext, pcrIndex, &number, NULL);
58           else
59                     result = TCS_GetPcrEvent_Internal(hContext, pcrIndex, &number, &pEvent);
60 
61           if (result == TSS_SUCCESS) {
62                     initData(&data->comm, 2);
63                     if (setData(TCSD_PACKET_TYPE_UINT32, 0, &number, 0, &data->comm)) {
64                               if (lengthOnly == FALSE)
65                                         free_external_events(1, pEvent);
66                               free(pEvent);
67                               return TCSERR(TSS_E_INTERNAL_ERROR);
68                     }
69 
70                     if (lengthOnly == FALSE) {
71                               if (setData(TCSD_PACKET_TYPE_PCR_EVENT, 1, pEvent, 0, &data->comm)) {
72                                         free_external_events(1, pEvent);
73                                         free(pEvent);
74                                         return TCSERR(TSS_E_INTERNAL_ERROR);
75                               }
76                               free_external_events(1, pEvent);
77                               free(pEvent);
78                     }
79           } else
80 done:               initData(&data->comm, 0);
81 
82           data->comm.hdr.u.result = result;
83 
84           return TSS_SUCCESS;
85 }
86 
87 
88 TSS_RESULT
tcs_wrap_GetPcrEventsByPcr(struct tcsd_thread_data * data)89 tcs_wrap_GetPcrEventsByPcr(struct tcsd_thread_data *data)
90 {
91           TCS_CONTEXT_HANDLE hContext;
92           TSS_PCR_EVENT *ppEvents = NULL;
93           TSS_RESULT result;
94           UINT32 firstEvent, eventCount, totalSize, pcrIndex, i, j;
95 
96           if (getData(TCSD_PACKET_TYPE_UINT32, 0, &hContext, 0, &data->comm))
97                     return TCSERR(TSS_E_INTERNAL_ERROR);
98 
99           if ((result = ctx_verify_context(hContext)))
100                     goto done;
101 
102           LogDebugFn("thread %ld context %x", THREAD_ID, hContext);
103 
104           if (getData(TCSD_PACKET_TYPE_UINT32, 1, &pcrIndex, 0, &data->comm))
105                     return TCSERR(TSS_E_INTERNAL_ERROR);
106 
107           if (getData(TCSD_PACKET_TYPE_UINT32, 2, &firstEvent, 0, &data->comm))
108                     return TCSERR(TSS_E_INTERNAL_ERROR);
109 
110           if (getData(TCSD_PACKET_TYPE_UINT32, 3, &eventCount, 0, &data->comm))
111                     return TCSERR(TSS_E_INTERNAL_ERROR);
112 
113           result = TCS_GetPcrEventsByPcr_Internal(hContext, pcrIndex, firstEvent, &eventCount, &ppEvents);
114 
115           if (result == TSS_SUCCESS) {
116                     /* XXX totalSize not used */
117                     for (i = 0, totalSize = 0; i < eventCount; i++)
118                               totalSize += get_pcr_event_size(&(ppEvents[i]));
119 
120                     initData(&data->comm, eventCount + 1);
121                     if (setData(TCSD_PACKET_TYPE_UINT32, 0, &eventCount, 0, &data->comm)) {
122                               free_external_events(eventCount, ppEvents);
123                               free(ppEvents);
124                               return TCSERR(TSS_E_INTERNAL_ERROR);
125                     }
126 
127                     i = 1;
128                     for (j = 0; j < eventCount; j++) {
129                               if (setData(TCSD_PACKET_TYPE_PCR_EVENT, i++, &(ppEvents[j]), 0, &data->comm)) {
130                                         free_external_events(eventCount, ppEvents);
131                                         free(ppEvents);
132                                         return TCSERR(TSS_E_INTERNAL_ERROR);
133                               }
134                     }
135 
136                     free_external_events(eventCount, ppEvents);
137                     free(ppEvents);
138           } else
139 done:               initData(&data->comm, 0);
140 
141           data->comm.hdr.u.result = result;
142 
143           return TSS_SUCCESS;
144 }
145 
146 TSS_RESULT
tcs_wrap_GetPcrEventLog(struct tcsd_thread_data * data)147 tcs_wrap_GetPcrEventLog(struct tcsd_thread_data *data)
148 {
149           TCS_CONTEXT_HANDLE hContext;
150           TSS_PCR_EVENT *ppEvents;
151           TSS_RESULT result;
152           UINT32 eventCount, totalSize, i, j;
153 
154           if (getData(TCSD_PACKET_TYPE_UINT32, 0, &hContext, 0, &data->comm))
155                     return TCSERR(TSS_E_INTERNAL_ERROR);
156 
157           LogDebugFn("thread %ld context %x", THREAD_ID, hContext);
158 
159           result = TCS_GetPcrEventLog_Internal(hContext, &eventCount, &ppEvents);
160 
161           if (result == TSS_SUCCESS) {
162                     for (i = 0, totalSize = 0; i < eventCount; i++)
163                               totalSize += get_pcr_event_size(&(ppEvents[i]));
164 
165                     initData(&data->comm, eventCount + 1);
166                     if (setData(TCSD_PACKET_TYPE_UINT32, 0, &eventCount, 0, &data->comm)) {
167                               free_external_events(eventCount, ppEvents);
168                               free(ppEvents);
169                               return TCSERR(TSS_E_INTERNAL_ERROR);
170                     }
171 
172                     i = 1;
173                     for (j = 0; j < eventCount; j++) {
174                               if (setData(TCSD_PACKET_TYPE_PCR_EVENT, i++, &(ppEvents[j]), 0, &data->comm)) {
175                                         free_external_events(eventCount, ppEvents);
176                                         free(ppEvents);
177                                         return TCSERR(TSS_E_INTERNAL_ERROR);
178                               }
179                     }
180 
181                     free_external_events(eventCount, ppEvents);
182                     free(ppEvents);
183           } else
184                     initData(&data->comm, 0);
185 
186           data->comm.hdr.u.result = result;
187 
188           return TSS_SUCCESS;
189 }
190 
191 TSS_RESULT
tcs_wrap_LogPcrEvent(struct tcsd_thread_data * data)192 tcs_wrap_LogPcrEvent(struct tcsd_thread_data *data)
193 {
194           TCS_CONTEXT_HANDLE hContext;
195           TSS_PCR_EVENT event;
196           TSS_RESULT result;
197           UINT32 number;
198 
199           /* Receive */
200           if (getData(TCSD_PACKET_TYPE_UINT32, 0, &hContext, 0, &data->comm))
201                     return TCSERR(TSS_E_INTERNAL_ERROR);
202 
203           if ((result = ctx_verify_context(hContext)))
204                     goto done;
205 
206           LogDebugFn("thread %ld context %x", THREAD_ID, hContext);
207 
208           if (getData(TCSD_PACKET_TYPE_PCR_EVENT , 1, &event, 0, &data->comm))
209                     return TCSERR(TSS_E_INTERNAL_ERROR);
210 
211           result = TCS_LogPcrEvent_Internal(hContext, event, &number);
212 
213           if (result == TSS_SUCCESS) {
214                     initData(&data->comm, 1);
215                     if (setData(TCSD_PACKET_TYPE_UINT32, 0, &number, 0, &data->comm)) {
216                               return TCSERR(TSS_E_INTERNAL_ERROR);
217                     }
218           } else
219 done:               initData(&data->comm, 0);
220 
221           data->comm.hdr.u.result = result;
222 
223           return TSS_SUCCESS;
224 }
225 
226 void
LoadBlob_PCR_EVENT(UINT64 * offset,BYTE * blob,TSS_PCR_EVENT * event)227 LoadBlob_PCR_EVENT(UINT64 *offset, BYTE *blob, TSS_PCR_EVENT *event)
228 {
229           LoadBlob_VERSION(offset, blob, (TPM_VERSION *)&(event->versionInfo));
230           LoadBlob_UINT32(offset, event->ulPcrIndex, blob);
231           LoadBlob_UINT32(offset, event->eventType, blob);
232 
233           LoadBlob_UINT32(offset, event->ulPcrValueLength, blob);
234           if (event->ulPcrValueLength > 0)
235                     LoadBlob(offset, event->ulPcrValueLength, blob, event->rgbPcrValue);
236 
237           LoadBlob_UINT32(offset, event->ulEventLength, blob);
238           if (event->ulEventLength > 0)
239                     LoadBlob(offset, event->ulEventLength, blob, event->rgbEvent);
240 
241 }
242 
243 TSS_RESULT
UnloadBlob_PCR_EVENT(UINT64 * offset,BYTE * blob,TSS_PCR_EVENT * event)244 UnloadBlob_PCR_EVENT(UINT64 *offset, BYTE *blob, TSS_PCR_EVENT *event)
245 {
246           if (!event) {
247                     UINT32 ulPcrValueLength, ulEventLength;
248 
249                     UnloadBlob_VERSION(offset, blob, NULL);
250                     UnloadBlob_UINT32(offset, NULL, blob);
251                     UnloadBlob_UINT32(offset, NULL, blob);
252 
253                     UnloadBlob_UINT32(offset, &ulPcrValueLength, blob);
254                     (*offset) += ulPcrValueLength;
255 
256                     UnloadBlob_UINT32(offset, &ulEventLength, blob);
257                     (*offset) += ulEventLength;
258 
259                     return TSS_SUCCESS;
260           }
261 
262           UnloadBlob_VERSION(offset, blob, (TPM_VERSION *)&(event->versionInfo));
263           UnloadBlob_UINT32(offset, &event->ulPcrIndex, blob);
264           UnloadBlob_UINT32(offset, &event->eventType, blob);
265 
266           UnloadBlob_UINT32(offset, &event->ulPcrValueLength, blob);
267           if (event->ulPcrValueLength > 0) {
268                     event->rgbPcrValue = malloc(event->ulPcrValueLength);
269                     if (event->rgbPcrValue == NULL) {
270                               LogError("malloc of %u bytes failed.", event->ulPcrValueLength);
271                               return TCSERR(TSS_E_OUTOFMEMORY);
272                     }
273 
274                     UnloadBlob(offset, event->ulPcrValueLength, blob, event->rgbPcrValue);
275           } else {
276                     event->rgbPcrValue = NULL;
277           }
278 
279           UnloadBlob_UINT32(offset, &event->ulEventLength, blob);
280           if (event->ulEventLength > 0) {
281                     event->rgbEvent = malloc(event->ulEventLength);
282                     if (event->rgbEvent == NULL) {
283                               LogError("malloc of %u bytes failed.", event->ulEventLength);
284                               free(event->rgbPcrValue);
285                               return TCSERR(TSS_E_OUTOFMEMORY);
286                     }
287 
288                     UnloadBlob(offset, event->ulEventLength, blob, event->rgbEvent);
289           } else {
290                     event->rgbEvent = NULL;
291           }
292 
293           return TSS_SUCCESS;
294 }
295