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 
33 TCS_CONTEXT_HANDLE InternalContext = 0x30000000;
34 TSS_UUID SRK_UUID = TSS_UUID_SRK;
35 
36 
37 void
LogData(char * string,UINT32 data)38 LogData(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 
46 void
LogResult(char * string,TCPA_RESULT result)47 LogResult(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 
55 UINT16
Decode_UINT16(BYTE * in)56 Decode_UINT16(BYTE * in)
57 {
58 	UINT16 temp = 0;
59 	temp = (in[1] & 0xFF);
60 	temp |= (in[0] << 8);
61 	return temp;
62 }
63 
64 void
UINT64ToArray(UINT64 i,BYTE * out)65 UINT64ToArray(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 
77 void
UINT32ToArray(UINT32 i,BYTE * out)78 UINT32ToArray(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 
86 void
UINT16ToArray(UINT16 i,BYTE * out)87 UINT16ToArray(UINT16 i, BYTE * out)
88 {
89 	out[0] = (BYTE) ((i >> 8) & 0xFF);
90 	out[1] = (BYTE) (i & 0xFF);
91 }
92 
93 UINT32
Decode_UINT32(BYTE * y)94 Decode_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 
106 UINT64
Decode_UINT64(BYTE * y)107 Decode_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 
123 void
LoadBlob_UINT64(UINT64 * offset,UINT64 in,BYTE * blob)124 LoadBlob_UINT64(UINT64 *offset, UINT64 in, BYTE * blob)
125 {
126 	if (blob)
127 		UINT64ToArray(in, &blob[*offset]);
128 	*offset += sizeof(UINT64);
129 }
130 
131 void
LoadBlob_UINT32(UINT64 * offset,UINT32 in,BYTE * blob)132 LoadBlob_UINT32(UINT64 *offset, UINT32 in, BYTE * blob)
133 {
134 	if (blob)
135 		UINT32ToArray(in, &blob[*offset]);
136 	*offset += sizeof(UINT32);
137 }
138 
139 void
LoadBlob_UINT16(UINT64 * offset,UINT16 in,BYTE * blob)140 LoadBlob_UINT16(UINT64 *offset, UINT16 in, BYTE * blob)
141 {
142 	if (blob)
143 		UINT16ToArray(in, &blob[*offset]);
144 	*offset += sizeof(UINT16);
145 }
146 
147 void
UnloadBlob_UINT64(UINT64 * offset,UINT64 * out,BYTE * blob)148 UnloadBlob_UINT64(UINT64 *offset, UINT64 * out, BYTE * blob)
149 {
150 	if (out)
151 		*out = Decode_UINT64(&blob[*offset]);
152 	*offset += sizeof(UINT64);
153 }
154 
155 void
UnloadBlob_UINT32(UINT64 * offset,UINT32 * out,BYTE * blob)156 UnloadBlob_UINT32(UINT64 *offset, UINT32 * out, BYTE * blob)
157 {
158 	if (out)
159 		*out = Decode_UINT32(&blob[*offset]);
160 	*offset += sizeof(UINT32);
161 }
162 
163 void
UnloadBlob_UINT16(UINT64 * offset,UINT16 * out,BYTE * blob)164 UnloadBlob_UINT16(UINT64 *offset, UINT16 * out, BYTE * blob)
165 {
166 	if (out)
167 		*out = Decode_UINT16(&blob[*offset]);
168 	*offset += sizeof(UINT16);
169 }
170 
171 void
LoadBlob_BYTE(UINT64 * offset,BYTE data,BYTE * blob)172 LoadBlob_BYTE(UINT64 *offset, BYTE data, BYTE * blob)
173 {
174 	if (blob)
175 		blob[*offset] = data;
176 	(*offset)++;
177 }
178 
179 void
UnloadBlob_BYTE(UINT64 * offset,BYTE * dataOut,BYTE * blob)180 UnloadBlob_BYTE(UINT64 *offset, BYTE * dataOut, BYTE * blob)
181 {
182 	if (dataOut)
183 		*dataOut = blob[*offset];
184 	(*offset)++;
185 }
186 
187 void
LoadBlob_BOOL(UINT64 * offset,TSS_BOOL data,BYTE * blob)188 LoadBlob_BOOL(UINT64 *offset, TSS_BOOL data, BYTE * blob)
189 {
190 	if (blob)
191 		blob[*offset] = data;
192 	(*offset)++;
193 }
194 
195 void
UnloadBlob_BOOL(UINT64 * offset,TSS_BOOL * dataOut,BYTE * blob)196 UnloadBlob_BOOL(UINT64 *offset, TSS_BOOL *dataOut, BYTE * blob)
197 {
198 	if (dataOut)
199 		*dataOut = blob[*offset];
200 	(*offset)++;
201 }
202 
203 void
LoadBlob(UINT64 * offset,UINT32 size,BYTE * container,BYTE * object)204 LoadBlob(UINT64 *offset, UINT32 size, BYTE *container, BYTE *object)
205 {
206 	if (container)
207 		memcpy(&container[*offset], object, size);
208 	(*offset) += (UINT64) size;
209 }
210 
211 void
UnloadBlob(UINT64 * offset,UINT32 size,BYTE * container,BYTE * object)212 UnloadBlob(UINT64 *offset, UINT32 size, BYTE *container, BYTE *object)
213 {
214 	if (object)
215 		memcpy(object, &container[*offset], size);
216 	(*offset) += (UINT64) size;
217 }
218 
219 void
LoadBlob_Header(UINT16 tag,UINT32 paramSize,UINT32 ordinal,BYTE * blob)220 LoadBlob_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
235 TSS_RESULT
LogUnloadBlob_Header(BYTE * blob,UINT32 * size,char * file,int line)236 LogUnloadBlob_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
253 TSS_RESULT
UnloadBlob_Header(BYTE * blob,UINT32 * size)254 UnloadBlob_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 
265 void
LoadBlob_Auth(UINT64 * offset,BYTE * blob,TPM_AUTH * auth)266 LoadBlob_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 
274 void
UnloadBlob_Auth(UINT64 * offset,BYTE * blob,TPM_AUTH * auth)275 UnloadBlob_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 
290 void
UnloadBlob_VERSION(UINT64 * offset,BYTE * blob,TPM_VERSION * out)291 UnloadBlob_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 
304 void
LoadBlob_VERSION(UINT64 * offset,BYTE * blob,TPM_VERSION * ver)305 LoadBlob_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 
313 void
UnloadBlob_TCPA_VERSION(UINT64 * offset,BYTE * blob,TCPA_VERSION * out)314 UnloadBlob_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 
327 void
LoadBlob_TCPA_VERSION(UINT64 * offset,BYTE * blob,TCPA_VERSION * ver)328 LoadBlob_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 
336 TSS_RESULT
UnloadBlob_KEY_PARMS(UINT64 * offset,BYTE * blob,TCPA_KEY_PARMS * keyParms)337 UnloadBlob_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 
374 void
UnloadBlob_KEY_FLAGS(UINT64 * offset,BYTE * blob,TCPA_KEY_FLAGS * flags)375 UnloadBlob_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 
386 TSS_RESULT
UnloadBlob_CERTIFY_INFO(UINT64 * offset,BYTE * blob,TCPA_CERTIFY_INFO * certify)387 UnloadBlob_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 
462 TSS_RESULT
UnloadBlob_KEY_HANDLE_LIST(UINT64 * offset,BYTE * blob,TCPA_KEY_HANDLE_LIST * list)463 UnloadBlob_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 
496 void
LoadBlob_DIGEST(UINT64 * offset,BYTE * blob,TPM_DIGEST * digest)497 LoadBlob_DIGEST(UINT64 *offset, BYTE *blob, TPM_DIGEST *digest)
498 {
499 	LoadBlob(offset, TPM_SHA1_160_HASH_LEN, blob, digest->digest);
500 }
501 
502 void
UnloadBlob_DIGEST(UINT64 * offset,BYTE * blob,TPM_DIGEST * digest)503 UnloadBlob_DIGEST(UINT64 *offset, BYTE *blob, TPM_DIGEST *digest)
504 {
505 	UnloadBlob(offset, TPM_SHA1_160_HASH_LEN, blob, digest->digest);
506 }
507 
508 void
LoadBlob_NONCE(UINT64 * offset,BYTE * blob,TPM_NONCE * nonce)509 LoadBlob_NONCE(UINT64 *offset, BYTE *blob, TPM_NONCE *nonce)
510 {
511 	LoadBlob(offset, TCPA_NONCE_SIZE, blob, nonce->nonce);
512 }
513 
514 void
UnloadBlob_NONCE(UINT64 * offset,BYTE * blob,TPM_NONCE * nonce)515 UnloadBlob_NONCE(UINT64 *offset, BYTE *blob, TPM_NONCE *nonce)
516 {
517 	UnloadBlob(offset, TCPA_NONCE_SIZE, blob, nonce->nonce);
518 }
519 
520 void
LoadBlob_AUTHDATA(UINT64 * offset,BYTE * blob,TPM_AUTHDATA * authdata)521 LoadBlob_AUTHDATA(UINT64 *offset, BYTE *blob, TPM_AUTHDATA *authdata)
522 {
523 	LoadBlob(offset, TPM_SHA1_160_HASH_LEN, blob, authdata->authdata);
524 }
525 
526 void
UnloadBlob_AUTHDATA(UINT64 * offset,BYTE * blob,TPM_AUTHDATA * authdata)527 UnloadBlob_AUTHDATA(UINT64 *offset, BYTE *blob, TPM_AUTHDATA *authdata)
528 {
529 	UnloadBlob(offset, TPM_SHA1_160_HASH_LEN, blob, authdata->authdata);
530 }
531 
532