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