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-2007
8 *
9 */
10
11
12#include <stdlib.h>
13#include <stdio.h>
14#include <string.h>
15#include <unistd.h>
16#include <sys/types.h>
17#include <sys/stat.h>
18#include <sys/mman.h>
19#include <fcntl.h>
20#include <errno.h>
21
22#include "trousers/tss.h"
23#include "trousers_types.h"
24#include "trousers_types.h"
25#include "tcs_tsp.h"
26#include "tcs_utils.h"
27#include "tcs_int_literals.h"
28#include "capabilities.h"
29#include "tcsps.h"
30#include "tcslog.h"
31
32
33TCS_CONTEXT_HANDLE InternalContext = 0x30000000;
34TSS_UUID SRK_UUID = TSS_UUID_SRK;
35
36
37void
38LogData(char *string, UINT32 data)
39{
40#if 0
41	/* commenting out temporarily, logs getting too chatty */
42	LogDebug("%s %08x", string, data);
43#endif
44}
45
46void
47LogResult(char *string, TCPA_RESULT result)
48{
49#if 0
50	/* commenting out temporarily, logs getting too chatty */
51	LogDebug("Leaving %s with result 0x%08x", string, result);
52#endif
53}
54
55UINT16
56Decode_UINT16(BYTE * in)
57{
58	UINT16 temp = 0;
59	temp = (in[1] & 0xFF);
60	temp |= (in[0] << 8);
61	return temp;
62}
63
64void
65UINT64ToArray(UINT64 i, BYTE * out)
66{
67	out[0] = (BYTE) ((i >> 56) & 0xFF);
68	out[1] = (BYTE) ((i >> 48) & 0xFF);
69	out[2] = (BYTE) ((i >> 40) & 0xFF);
70	out[3] = (BYTE) ((i >> 32) & 0xFF);
71	out[4] = (BYTE) ((i >> 24) & 0xFF);
72	out[5] = (BYTE) ((i >> 16) & 0xFF);
73	out[6] = (BYTE) ((i >> 8) & 0xFF);
74	out[7] = (BYTE) (i & 0xFF);
75}
76
77void
78UINT32ToArray(UINT32 i, BYTE * out)
79{
80	out[0] = (BYTE) ((i >> 24) & 0xFF);
81	out[1] = (BYTE) ((i >> 16) & 0xFF);
82	out[2] = (BYTE) ((i >> 8) & 0xFF);
83	out[3] = (BYTE) (i & 0xFF);
84}
85
86void
87UINT16ToArray(UINT16 i, BYTE * out)
88{
89	out[0] = (BYTE) ((i >> 8) & 0xFF);
90	out[1] = (BYTE) (i & 0xFF);
91}
92
93UINT32
94Decode_UINT32(BYTE * y)
95{
96	UINT32 x = 0;
97
98	x = y[0];
99	x = ((x << 8) | (y[1] & 0xFF));
100	x = ((x << 8) | (y[2] & 0xFF));
101	x = ((x << 8) | (y[3] & 0xFF));
102
103	return x;
104}
105
106UINT64
107Decode_UINT64(BYTE *y)
108{
109	UINT64 x = 0;
110
111	x = y[0];
112	x = ((x << 8) | (y[1] & 0xFF));
113	x = ((x << 8) | (y[2] & 0xFF));
114	x = ((x << 8) | (y[3] & 0xFF));
115	x = ((x << 8) | (y[4] & 0xFF));
116	x = ((x << 8) | (y[5] & 0xFF));
117	x = ((x << 8) | (y[6] & 0xFF));
118	x = ((x << 8) | (y[7] & 0xFF));
119
120	return x;
121}
122
123void
124LoadBlob_UINT64(UINT64 *offset, UINT64 in, BYTE * blob)
125{
126	if (blob)
127		UINT64ToArray(in, &blob[*offset]);
128	*offset += sizeof(UINT64);
129}
130
131void
132LoadBlob_UINT32(UINT64 *offset, UINT32 in, BYTE * blob)
133{
134	if (blob)
135		UINT32ToArray(in, &blob[*offset]);
136	*offset += sizeof(UINT32);
137}
138
139void
140LoadBlob_UINT16(UINT64 *offset, UINT16 in, BYTE * blob)
141{
142	if (blob)
143		UINT16ToArray(in, &blob[*offset]);
144	*offset += sizeof(UINT16);
145}
146
147void
148UnloadBlob_UINT64(UINT64 *offset, UINT64 * out, BYTE * blob)
149{
150	if (out)
151		*out = Decode_UINT64(&blob[*offset]);
152	*offset += sizeof(UINT64);
153}
154
155void
156UnloadBlob_UINT32(UINT64 *offset, UINT32 * out, BYTE * blob)
157{
158	if (out)
159		*out = Decode_UINT32(&blob[*offset]);
160	*offset += sizeof(UINT32);
161}
162
163void
164UnloadBlob_UINT16(UINT64 *offset, UINT16 * out, BYTE * blob)
165{
166	if (out)
167		*out = Decode_UINT16(&blob[*offset]);
168	*offset += sizeof(UINT16);
169}
170
171void
172LoadBlob_BYTE(UINT64 *offset, BYTE data, BYTE * blob)
173{
174	if (blob)
175		blob[*offset] = data;
176	(*offset)++;
177}
178
179void
180UnloadBlob_BYTE(UINT64 *offset, BYTE * dataOut, BYTE * blob)
181{
182	if (dataOut)
183		*dataOut = blob[*offset];
184	(*offset)++;
185}
186
187void
188LoadBlob_BOOL(UINT64 *offset, TSS_BOOL data, BYTE * blob)
189{
190	if (blob)
191		blob[*offset] = data;
192	(*offset)++;
193}
194
195void
196UnloadBlob_BOOL(UINT64 *offset, TSS_BOOL *dataOut, BYTE * blob)
197{
198	if (dataOut)
199		*dataOut = blob[*offset];
200	(*offset)++;
201}
202
203void
204LoadBlob(UINT64 *offset, UINT32 size, BYTE *container, BYTE *object)
205{
206	if (container)
207		memcpy(&container[*offset], object, size);
208	(*offset) += (UINT64) size;
209}
210
211void
212UnloadBlob(UINT64 *offset, UINT32 size, BYTE *container, BYTE *object)
213{
214	if (object)
215		memcpy(object, &container[*offset], size);
216	(*offset) += (UINT64) size;
217}
218
219void
220LoadBlob_Header(UINT16 tag, UINT32 paramSize, UINT32 ordinal, BYTE * blob)
221{
222
223	UINT16ToArray(tag, &blob[0]);
224	LogData("Header Tag:", tag);
225	UINT32ToArray(paramSize, &blob[2]);
226	LogData("Header ParamSize:", paramSize);
227	UINT32ToArray(ordinal, &blob[6]);
228	LogData("Header Ordinal:", ordinal);
229#if 0
230	LogInfo("Blob's TPM Ordinal: 0x%x", ordinal);
231#endif
232}
233
234#ifdef TSS_DEBUG
235TSS_RESULT
236LogUnloadBlob_Header(BYTE * blob, UINT32 * size, char *file, int line)
237{
238	TSS_RESULT result;
239
240	UINT16 temp = Decode_UINT16(blob);
241	LogData("UnloadBlob_Tag:", (temp));
242	*size = Decode_UINT32(&blob[2]);
243	LogData("UnloadBlob_Header, size:", *size);
244	LogData("UnloadBlob_Header, returnCode:", Decode_UINT32(&blob[6]));
245
246	if ((result = Decode_UINT32(&blob[6]))) {
247		LogTPMERR(result, file, line);
248	}
249
250	return result;
251}
252#else
253TSS_RESULT
254UnloadBlob_Header(BYTE * blob, UINT32 * size)
255{
256	UINT16 temp = Decode_UINT16(blob);
257	LogData("UnloadBlob_Tag:", (temp));
258	*size = Decode_UINT32(&blob[2]);
259	LogData("UnloadBlob_Header, size:", *size);
260	LogData("UnloadBlob_Header, returnCode:", Decode_UINT32(&blob[6]));
261	return Decode_UINT32(&blob[6]);
262}
263#endif
264
265void
266LoadBlob_Auth(UINT64 *offset, BYTE * blob, TPM_AUTH * auth)
267{
268	LoadBlob_UINT32(offset, auth->AuthHandle, blob);
269	LoadBlob(offset, TCPA_NONCE_SIZE, blob, auth->NonceOdd.nonce);
270	LoadBlob_BOOL(offset, auth->fContinueAuthSession, blob);
271	LoadBlob(offset, TCPA_AUTHDATA_SIZE, blob, (BYTE *)&auth->HMAC);
272}
273
274void
275UnloadBlob_Auth(UINT64 *offset, BYTE * blob, TPM_AUTH * auth)
276{
277	if (!auth) {
278		UnloadBlob(offset, TCPA_NONCE_SIZE, blob, NULL);
279		UnloadBlob_BOOL(offset, NULL, blob);
280		UnloadBlob(offset, TCPA_DIGEST_SIZE, blob, NULL);
281
282		return;
283	}
284
285	UnloadBlob(offset, TCPA_NONCE_SIZE, blob, auth->NonceEven.nonce);
286	UnloadBlob_BOOL(offset, &auth->fContinueAuthSession, blob);
287	UnloadBlob(offset, TCPA_DIGEST_SIZE, blob, (BYTE *)&auth->HMAC);
288}
289
290void
291UnloadBlob_VERSION(UINT64 *offset, BYTE *blob, TPM_VERSION *out)
292{
293	if (!out) {
294		*offset += (sizeof(BYTE) * 4);
295		return;
296	}
297
298	UnloadBlob_BYTE(offset, &out->major, blob);
299	UnloadBlob_BYTE(offset, &out->minor, blob);
300	UnloadBlob_BYTE(offset, &out->revMajor, blob);
301	UnloadBlob_BYTE(offset, &out->revMinor, blob);
302}
303
304void
305LoadBlob_VERSION(UINT64 *offset, BYTE *blob, TPM_VERSION *ver)
306{
307	LoadBlob_BYTE(offset, ver->major, blob);
308	LoadBlob_BYTE(offset, ver->minor, blob);
309	LoadBlob_BYTE(offset, ver->revMajor, blob);
310	LoadBlob_BYTE(offset, ver->revMinor, blob);
311}
312
313void
314UnloadBlob_TCPA_VERSION(UINT64 *offset, BYTE *blob, TCPA_VERSION *out)
315{
316	if (!out) {
317		*offset += (sizeof(BYTE) * 4);
318		return;
319	}
320
321	UnloadBlob_BYTE(offset, &out->major, blob);
322	UnloadBlob_BYTE(offset, &out->minor, blob);
323	UnloadBlob_BYTE(offset, &out->revMajor, blob);
324	UnloadBlob_BYTE(offset, &out->revMinor, blob);
325}
326
327void
328LoadBlob_TCPA_VERSION(UINT64 *offset, BYTE *blob, TCPA_VERSION *ver)
329{
330	LoadBlob_BYTE(offset, ver->major, blob);
331	LoadBlob_BYTE(offset, ver->minor, blob);
332	LoadBlob_BYTE(offset, ver->revMajor, blob);
333	LoadBlob_BYTE(offset, ver->revMinor, blob);
334}
335
336TSS_RESULT
337UnloadBlob_KEY_PARMS(UINT64 *offset, BYTE *blob, TCPA_KEY_PARMS *keyParms)
338{
339	if (!keyParms) {
340		UINT32 parmSize;
341
342		UnloadBlob_UINT32(offset, NULL, blob);
343		UnloadBlob_UINT16(offset, NULL, blob);
344		UnloadBlob_UINT16(offset, NULL, blob);
345		UnloadBlob_UINT32(offset, &parmSize, blob);
346
347		if (parmSize > 0)
348			UnloadBlob(offset, parmSize, blob, NULL);
349
350		return TSS_SUCCESS;
351	}
352
353	UnloadBlob_UINT32(offset, &keyParms->algorithmID, blob);
354	UnloadBlob_UINT16(offset, &keyParms->encScheme, blob);
355	UnloadBlob_UINT16(offset, &keyParms->sigScheme, blob);
356	UnloadBlob_UINT32(offset, &keyParms->parmSize, blob);
357
358	if (keyParms->parmSize == 0)
359		keyParms->parms = NULL;
360	else {
361		keyParms->parms = malloc(keyParms->parmSize);
362		if (keyParms->parms == NULL) {
363			LogError("malloc of %u bytes failed.", keyParms->parmSize);
364			keyParms->parmSize = 0;
365			return TCSERR(TSS_E_OUTOFMEMORY);
366		}
367
368		UnloadBlob(offset, keyParms->parmSize, blob, keyParms->parms);
369	}
370
371	return TSS_SUCCESS;
372}
373
374void
375UnloadBlob_KEY_FLAGS(UINT64 *offset, BYTE *blob, TCPA_KEY_FLAGS *flags)
376{
377	if (!flags) {
378		UnloadBlob_UINT32(offset, NULL, blob);
379
380		return;
381	}
382
383	UnloadBlob_UINT32(offset, flags, blob);
384}
385
386TSS_RESULT
387UnloadBlob_CERTIFY_INFO(UINT64 *offset, BYTE *blob, TCPA_CERTIFY_INFO *certify)
388{
389	TSS_RESULT rc;
390
391	if (!certify) {
392		TPM_VERSION version;
393		UINT32 size;
394
395		UnloadBlob_VERSION(offset, blob, &version);
396		UnloadBlob_UINT16(offset, NULL, blob);
397		UnloadBlob_KEY_FLAGS(offset, blob, NULL);
398		UnloadBlob_BOOL(offset, NULL, blob);
399
400		if ((rc = UnloadBlob_KEY_PARMS(offset, blob, NULL)))
401			return rc;
402
403		UnloadBlob(offset, TCPA_DIGEST_SIZE, blob, NULL);
404		UnloadBlob(offset, TCPA_NONCE_SIZE, blob, NULL);
405		UnloadBlob_BOOL(offset, NULL, blob);
406		UnloadBlob_UINT32(offset, &size, blob);
407
408		if (size > 0)
409			UnloadBlob(offset, size, blob, NULL);
410
411		if (Decode_UINT16((BYTE *) &version) == TPM_TAG_CERTIFY_INFO2){
412			/* This is a TPM_CERTIFY_INFO2 structure. */
413			/* Read migrationAuthority. */
414			UnloadBlob_UINT32(offset, &size, blob);
415			if (size > 0)
416				UnloadBlob(offset, size, blob, NULL);
417		}
418
419		return TSS_SUCCESS;
420	}
421
422	UnloadBlob_VERSION(offset, blob, (TPM_VERSION *)&certify->version);
423	UnloadBlob_UINT16(offset, &certify->keyUsage, blob);
424	UnloadBlob_KEY_FLAGS(offset, blob, &certify->keyFlags);
425	UnloadBlob_BOOL(offset, (TSS_BOOL *)&certify->authDataUsage, blob);
426
427	if ((rc = UnloadBlob_KEY_PARMS(offset, blob, &certify->algorithmParms)))
428		return rc;
429
430	UnloadBlob(offset, TCPA_DIGEST_SIZE, blob, certify->pubkeyDigest.digest);
431	UnloadBlob(offset, TCPA_NONCE_SIZE, blob, certify->data.nonce);
432	UnloadBlob_BOOL(offset, (TSS_BOOL *)&certify->parentPCRStatus, blob);
433	UnloadBlob_UINT32(offset, &certify->PCRInfoSize, blob);
434
435	if (certify->PCRInfoSize > 0) {
436		certify->PCRInfo = (BYTE *)malloc(certify->PCRInfoSize);
437		if (certify->PCRInfo == NULL) {
438			LogError("malloc of %u bytes failed.", certify->PCRInfoSize);
439			certify->PCRInfoSize = 0;
440			free(certify->algorithmParms.parms);
441			certify->algorithmParms.parms = NULL;
442			certify->algorithmParms.parmSize = 0;
443			return TCSERR(TSS_E_OUTOFMEMORY);
444		}
445		UnloadBlob(offset, certify->PCRInfoSize, blob, certify->PCRInfo);
446	} else {
447		certify->PCRInfo = NULL;
448	}
449
450	if (Decode_UINT16((BYTE *) &certify->version) == TPM_TAG_CERTIFY_INFO2){
451		/* This is a TPM_CERTIFY_INFO2 structure. */
452		/* Read migrationAuthority. */
453		UINT32 size;
454		UnloadBlob_UINT32(offset, &size, blob);
455		if (size > 0)
456			UnloadBlob(offset, size, blob, NULL);
457	}
458
459	return TSS_SUCCESS;
460}
461
462TSS_RESULT
463UnloadBlob_KEY_HANDLE_LIST(UINT64 *offset, BYTE *blob, TCPA_KEY_HANDLE_LIST *list)
464{
465	UINT16 i;
466
467	if (!list) {
468		UINT16 size;
469
470		UnloadBlob_UINT16(offset, &size, blob);
471
472		*offset += (size * sizeof(UINT32));
473
474		return TSS_SUCCESS;
475	}
476
477	UnloadBlob_UINT16(offset, &list->loaded, blob);
478	if (list->loaded == 0) {
479		list->handle = NULL;
480		return TSS_SUCCESS;
481	}
482
483	list->handle = malloc(list->loaded * sizeof (UINT32));
484        if (list->handle == NULL) {
485		LogError("malloc of %zd bytes failed.", list->loaded * sizeof (UINT32));
486		list->loaded = 0;
487                return TCSERR(TSS_E_OUTOFMEMORY);
488        }
489
490	for (i = 0; i < list->loaded; i++)
491		UnloadBlob_UINT32(offset, &list->handle[i], blob);
492
493	return TSS_SUCCESS;
494}
495
496void
497LoadBlob_DIGEST(UINT64 *offset, BYTE *blob, TPM_DIGEST *digest)
498{
499	LoadBlob(offset, TPM_SHA1_160_HASH_LEN, blob, digest->digest);
500}
501
502void
503UnloadBlob_DIGEST(UINT64 *offset, BYTE *blob, TPM_DIGEST *digest)
504{
505	UnloadBlob(offset, TPM_SHA1_160_HASH_LEN, blob, digest->digest);
506}
507
508void
509LoadBlob_NONCE(UINT64 *offset, BYTE *blob, TPM_NONCE *nonce)
510{
511	LoadBlob(offset, TCPA_NONCE_SIZE, blob, nonce->nonce);
512}
513
514void
515UnloadBlob_NONCE(UINT64 *offset, BYTE *blob, TPM_NONCE *nonce)
516{
517	UnloadBlob(offset, TCPA_NONCE_SIZE, blob, nonce->nonce);
518}
519
520void
521LoadBlob_AUTHDATA(UINT64 *offset, BYTE *blob, TPM_AUTHDATA *authdata)
522{
523	LoadBlob(offset, TPM_SHA1_160_HASH_LEN, blob, authdata->authdata);
524}
525
526void
527UnloadBlob_AUTHDATA(UINT64 *offset, BYTE *blob, TPM_AUTHDATA *authdata)
528{
529	UnloadBlob(offset, TPM_SHA1_160_HASH_LEN, blob, authdata->authdata);
530}
531
532