xref: /netbsd-src/crypto/external/cpl/trousers/dist/src/trspi/trousers.c (revision b83ebeba7f767758d2778bb0f9d7a76534253621)
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/mman.h>
18 #include <langinfo.h>
19 #include <iconv.h>
20 #include <wchar.h>
21 #include <errno.h>
22 
23 #include "trousers/tss.h"
24 #include "trousers_types.h"
25 #include "trousers/trousers.h"
26 #include "trousers_types.h"
27 #include "spi_utils.h"
28 #include "capabilities.h"
29 #include "tsplog.h"
30 #include "obj.h"
31 
32 
33 void
34 Trspi_UnloadBlob_NONCE(UINT64 *offset, BYTE *blob, TPM_NONCE *n)
35 {
36 	if (!n) {
37 		(*offset) += TPM_SHA1_160_HASH_LEN;
38 		return;
39 	}
40 
41 	Trspi_UnloadBlob(offset, TPM_SHA1_160_HASH_LEN, blob, n->nonce);
42 }
43 
44 void
45 Trspi_LoadBlob_NONCE(UINT64 *offset, BYTE *blob, TPM_NONCE *n)
46 {
47 	Trspi_LoadBlob(offset, TPM_SHA1_160_HASH_LEN, blob, n->nonce);
48 }
49 
50 void
51 Trspi_LoadBlob_DIGEST(UINT64 *offset, BYTE *blob, TPM_DIGEST *digest)
52 {
53 	Trspi_LoadBlob(offset, TPM_SHA1_160_HASH_LEN, blob, digest->digest);
54 }
55 
56 void
57 Trspi_UnloadBlob_DIGEST(UINT64 *offset, BYTE *blob, TPM_DIGEST *digest)
58 {
59 	if (!digest) {
60 		(*offset) += TPM_SHA1_160_HASH_LEN;
61 		return;
62 	}
63 
64 	Trspi_UnloadBlob(offset, TPM_SHA1_160_HASH_LEN, blob, digest->digest);
65 }
66 
67 void
68 Trspi_LoadBlob_PUBKEY(UINT64 *offset, BYTE *blob, TCPA_PUBKEY *pubKey)
69 {
70 	Trspi_LoadBlob_KEY_PARMS(offset, blob, &pubKey->algorithmParms);
71 	Trspi_LoadBlob_STORE_PUBKEY(offset, blob, &pubKey->pubKey);
72 }
73 
74 TSS_RESULT
75 Trspi_UnloadBlob_PUBKEY(UINT64 *offset, BYTE *blob, TCPA_PUBKEY *pubKey)
76 {
77 	TSS_RESULT result;
78 
79 	if (!pubKey) {
80 		(void)Trspi_UnloadBlob_KEY_PARMS(offset, blob, NULL);
81 		(void)Trspi_UnloadBlob_STORE_PUBKEY(offset, blob, NULL);
82 
83 		return TSS_SUCCESS;
84 	}
85 
86 	if ((result = Trspi_UnloadBlob_KEY_PARMS(offset, blob, &pubKey->algorithmParms)))
87 		return result;
88 	if ((result = Trspi_UnloadBlob_STORE_PUBKEY(offset, blob, &pubKey->pubKey))) {
89 		free(pubKey->pubKey.key);
90 		free(pubKey->algorithmParms.parms);
91 		pubKey->pubKey.key = NULL;
92 		pubKey->pubKey.keyLength = 0;
93 		pubKey->algorithmParms.parms = NULL;
94 		pubKey->algorithmParms.parmSize = 0;
95 		return result;
96 	}
97 
98 	return TSS_SUCCESS;
99 }
100 
101 void
102 Trspi_LoadBlob(UINT64 *offset, size_t size, BYTE *to, BYTE *from)
103 {
104 	if (size == 0)
105 		return;
106 	if (to)
107 		memcpy(&to[(*offset)], from, size);
108 	(*offset) += size;
109 }
110 
111 void
112 Trspi_UnloadBlob(UINT64 *offset, size_t size, BYTE *from, BYTE *to)
113 {
114 	if (size <= 0)
115 		return;
116 	if (to)
117 		memcpy(to, &from[*offset], size);
118 	(*offset) += size;
119 }
120 
121 void
122 Trspi_LoadBlob_BYTE(UINT64 *offset, BYTE data, BYTE *blob)
123 {
124 	if (blob)
125 		blob[*offset] = data;
126 	(*offset)++;
127 }
128 
129 void
130 Trspi_UnloadBlob_BYTE(UINT64 *offset, BYTE *dataOut, BYTE *blob)
131 {
132 	if (dataOut)
133 		*dataOut = blob[*offset];
134 	(*offset)++;
135 }
136 
137 void
138 Trspi_LoadBlob_BOOL(UINT64 *offset, TSS_BOOL data, BYTE *blob)
139 {
140 	if (blob)
141 		blob[*offset] = (BYTE) data;
142 	(*offset)++;
143 }
144 
145 void
146 Trspi_UnloadBlob_BOOL(UINT64 *offset, TSS_BOOL *dataOut, BYTE *blob)
147 {
148 	if (dataOut)
149 		*dataOut = blob[*offset];
150 	(*offset)++;
151 }
152 
153 void
154 Trspi_LoadBlob_UINT64(UINT64 *offset, UINT64 in, BYTE *blob)
155 {
156 	if (blob)
157 		UINT64ToArray(in, &blob[*offset]);
158 	(*offset) += sizeof(UINT64);
159 }
160 
161 void
162 Trspi_LoadBlob_UINT32(UINT64 *offset, UINT32 in, BYTE *blob)
163 {
164 	if (blob)
165 		UINT32ToArray(in, &blob[*offset]);
166 	(*offset) += sizeof(UINT32);
167 }
168 
169 void
170 Trspi_LoadBlob_UINT16(UINT64 *offset, UINT16 in, BYTE *blob)
171 {
172 	if (blob)
173 		UINT16ToArray(in, &blob[*offset]);
174 	(*offset) += sizeof(UINT16);
175 }
176 
177 void
178 Trspi_UnloadBlob_UINT64(UINT64 *offset, UINT64 *out, BYTE *blob)
179 {
180 	if (out)
181 		*out = Decode_UINT64(&blob[*offset]);
182 	(*offset) += sizeof(UINT64);
183 }
184 
185 void
186 Trspi_UnloadBlob_UINT32(UINT64 *offset, UINT32 *out, BYTE *blob)
187 {
188 	if (out)
189 		*out = Decode_UINT32(&blob[*offset]);
190 	(*offset) += sizeof(UINT32);
191 }
192 
193 void
194 Trspi_UnloadBlob_UINT16(UINT64 *offset, UINT16 *out, BYTE *blob)
195 {
196 	if (out)
197 		*out = Decode_UINT16(&blob[*offset]);
198 	(*offset) += sizeof(UINT16);
199 }
200 
201 void
202 Trspi_LoadBlob_RSA_KEY_PARMS(UINT64 *offset, BYTE *blob, TCPA_RSA_KEY_PARMS *parms)
203 {
204 	Trspi_LoadBlob_UINT32(offset, parms->keyLength, blob);
205 	Trspi_LoadBlob_UINT32(offset, parms->numPrimes, blob);
206 	Trspi_LoadBlob_UINT32(offset, parms->exponentSize, blob);
207 
208 	if (parms->exponentSize > 0)
209 		Trspi_LoadBlob(offset, parms->exponentSize, blob, parms->exponent);
210 }
211 
212 void
213 Trspi_UnloadBlob_TSS_VERSION(UINT64 *offset, BYTE *blob, TSS_VERSION *out)
214 {
215 	if (!out) {
216 		Trspi_UnloadBlob_BYTE(offset, NULL, blob);
217 		Trspi_UnloadBlob_BYTE(offset, NULL, blob);
218 		Trspi_UnloadBlob_BYTE(offset, NULL, blob);
219 		Trspi_UnloadBlob_BYTE(offset, NULL, blob);
220 
221 		return;
222 	}
223 
224 	Trspi_UnloadBlob_BYTE(offset, &out->bMajor, blob);
225 	Trspi_UnloadBlob_BYTE(offset, &out->bMinor, blob);
226 	Trspi_UnloadBlob_BYTE(offset, &out->bRevMajor, blob);
227 	Trspi_UnloadBlob_BYTE(offset, &out->bRevMinor, blob);
228 }
229 
230 void
231 Trspi_LoadBlob_TSS_VERSION(UINT64 *offset, BYTE *blob, TSS_VERSION version)
232 {
233 	Trspi_LoadBlob_BYTE(offset, version.bMajor, blob);
234 	Trspi_LoadBlob_BYTE(offset, version.bMinor, blob);
235 	Trspi_LoadBlob_BYTE(offset, version.bRevMajor, blob);
236 	Trspi_LoadBlob_BYTE(offset, version.bRevMinor, blob);
237 }
238 
239 void
240 Trspi_UnloadBlob_TCPA_VERSION(UINT64 *offset, BYTE *blob, TCPA_VERSION *out)
241 {
242 	if (!out) {
243 		Trspi_UnloadBlob_BYTE(offset, NULL, blob);
244 		Trspi_UnloadBlob_BYTE(offset, NULL, blob);
245 		Trspi_UnloadBlob_BYTE(offset, NULL, blob);
246 		Trspi_UnloadBlob_BYTE(offset, NULL, blob);
247 
248 		return;
249 	}
250 
251 	Trspi_UnloadBlob_BYTE(offset, &out->major, blob);
252 	Trspi_UnloadBlob_BYTE(offset, &out->minor, blob);
253 	Trspi_UnloadBlob_BYTE(offset, &out->revMajor, blob);
254 	Trspi_UnloadBlob_BYTE(offset, &out->revMinor, blob);
255 }
256 
257 void
258 Trspi_LoadBlob_TCPA_VERSION(UINT64 *offset, BYTE *blob, TCPA_VERSION version)
259 {
260 	Trspi_LoadBlob_BYTE(offset, version.major, blob);
261 	Trspi_LoadBlob_BYTE(offset, version.minor, blob);
262 	Trspi_LoadBlob_BYTE(offset, version.revMajor, blob);
263 	Trspi_LoadBlob_BYTE(offset, version.revMinor, blob);
264 }
265 
266 TSS_RESULT
267 Trspi_UnloadBlob_PCR_INFO(UINT64 *offset, BYTE *blob, TCPA_PCR_INFO *pcr)
268 {
269 	TSS_RESULT result;
270 
271 	if (!pcr) {
272 		(void)Trspi_UnloadBlob_PCR_SELECTION(offset, blob, NULL);
273 		Trspi_UnloadBlob_DIGEST(offset, blob, NULL);
274 		Trspi_UnloadBlob_DIGEST(offset, blob, NULL);
275 
276 		return TSS_SUCCESS;
277 	}
278 
279 	if ((result = Trspi_UnloadBlob_PCR_SELECTION(offset, blob, &pcr->pcrSelection)))
280 		return result;
281 	Trspi_UnloadBlob_DIGEST(offset, blob, &pcr->digestAtRelease);
282 	Trspi_UnloadBlob_DIGEST(offset, blob, &pcr->digestAtCreation);
283 
284 	return TSS_SUCCESS;
285 }
286 
287 void
288 Trspi_LoadBlob_PCR_INFO(UINT64 *offset, BYTE *blob, TCPA_PCR_INFO *pcr)
289 {
290 	Trspi_LoadBlob_PCR_SELECTION(offset, blob, &pcr->pcrSelection);
291 	Trspi_LoadBlob_DIGEST(offset, blob, &pcr->digestAtRelease);
292 	Trspi_LoadBlob_DIGEST(offset, blob, &pcr->digestAtCreation);
293 }
294 
295 TSS_RESULT
296 Trspi_UnloadBlob_PCR_INFO_LONG(UINT64 *offset, BYTE *blob, TPM_PCR_INFO_LONG *pcr)
297 {
298 	TSS_RESULT result;
299 
300 	if (!pcr) {
301 		Trspi_UnloadBlob_UINT16(offset, NULL, blob);
302 		Trspi_UnloadBlob_BYTE(offset, NULL, blob);
303 		Trspi_UnloadBlob_BYTE(offset, NULL, blob);
304 		Trspi_UnloadBlob_PCR_SELECTION(offset, blob, NULL);
305 		Trspi_UnloadBlob_PCR_SELECTION(offset, blob, NULL);
306 		Trspi_UnloadBlob_DIGEST(offset, blob, NULL);
307 		Trspi_UnloadBlob_DIGEST(offset, blob, NULL);
308 
309 		return TSS_SUCCESS;
310 	}
311 
312 	Trspi_UnloadBlob_UINT16(offset, &pcr->tag, blob);
313 	Trspi_UnloadBlob_BYTE(offset, &pcr->localityAtCreation, blob);
314 	Trspi_UnloadBlob_BYTE(offset, &pcr->localityAtRelease, blob);
315 	if ((result = Trspi_UnloadBlob_PCR_SELECTION(offset, blob, &pcr->creationPCRSelection)))
316 		return result;
317 	if ((result = Trspi_UnloadBlob_PCR_SELECTION(offset, blob, &pcr->releasePCRSelection)))
318 		return result;
319 	Trspi_UnloadBlob_DIGEST(offset, blob, &pcr->digestAtCreation);
320 	Trspi_UnloadBlob_DIGEST(offset, blob, &pcr->digestAtRelease);
321 
322 	return TSS_SUCCESS;
323 }
324 
325 void
326 Trspi_LoadBlob_PCR_INFO_LONG(UINT64 *offset, BYTE *blob, TPM_PCR_INFO_LONG *pcr)
327 {
328 	Trspi_LoadBlob_UINT16(offset, pcr->tag, blob);
329 	Trspi_LoadBlob_BYTE(offset, pcr->localityAtCreation, blob);
330 	Trspi_LoadBlob_BYTE(offset, pcr->localityAtRelease, blob);
331 	Trspi_LoadBlob_PCR_SELECTION(offset, blob, &pcr->creationPCRSelection);
332 	Trspi_LoadBlob_PCR_SELECTION(offset, blob, &pcr->releasePCRSelection);
333 	Trspi_LoadBlob_DIGEST(offset, blob, &pcr->digestAtCreation);
334 	Trspi_LoadBlob_DIGEST(offset, blob, &pcr->digestAtRelease);
335 }
336 
337 TSS_RESULT
338 Trspi_UnloadBlob_PCR_INFO_SHORT(UINT64 *offset, BYTE *blob, TPM_PCR_INFO_SHORT *pcr)
339 {
340 	TSS_RESULT result;
341 
342 	if (!pcr) {
343 		Trspi_UnloadBlob_PCR_SELECTION(offset, blob, NULL);
344 		Trspi_UnloadBlob_BYTE(offset, NULL, blob);
345 		Trspi_UnloadBlob_DIGEST(offset, blob, NULL);
346 
347 		return TSS_SUCCESS;
348 	}
349 
350 	if ((result = Trspi_UnloadBlob_PCR_SELECTION(offset, blob, &pcr->pcrSelection)))
351 		return result;
352 	Trspi_UnloadBlob_BYTE(offset, &pcr->localityAtRelease, blob);
353 	Trspi_UnloadBlob_DIGEST(offset, blob, &pcr->digestAtRelease);
354 
355 	return TSS_SUCCESS;
356 }
357 
358 void
359 Trspi_LoadBlob_PCR_INFO_SHORT(UINT64 *offset, BYTE *blob, TPM_PCR_INFO_SHORT *pcr)
360 {
361 	Trspi_LoadBlob_PCR_SELECTION(offset, blob, &pcr->pcrSelection);
362 	Trspi_LoadBlob_BYTE(offset, pcr->localityAtRelease, blob);
363 	Trspi_LoadBlob_DIGEST(offset, blob, &pcr->digestAtRelease);
364 }
365 
366 TSS_RESULT
367 Trspi_UnloadBlob_PCR_SELECTION(UINT64 *offset, BYTE *blob, TCPA_PCR_SELECTION *pcr)
368 {
369 	if (!pcr) {
370 		UINT16 sizeOfSelect;
371 
372 		Trspi_UnloadBlob_UINT16(offset, &sizeOfSelect, blob);
373 		Trspi_UnloadBlob(offset, sizeOfSelect, blob, NULL);
374 
375 		return TSS_SUCCESS;
376 	}
377 
378 	Trspi_UnloadBlob_UINT16(offset, &pcr->sizeOfSelect, blob);
379 
380 	if (pcr->sizeOfSelect > 0) {
381 		pcr->pcrSelect = calloc(1, pcr->sizeOfSelect);
382 		if (pcr->pcrSelect == NULL) {
383 			LogError("malloc of %u bytes failed.", pcr->sizeOfSelect);
384 			return TSPERR(TSS_E_OUTOFMEMORY);
385 		}
386 
387 		Trspi_UnloadBlob(offset, pcr->sizeOfSelect, blob, pcr->pcrSelect);
388 	} else {
389 		pcr->pcrSelect = NULL;
390 	}
391 
392 	return TSS_SUCCESS;
393 }
394 
395 void
396 Trspi_LoadBlob_PCR_SELECTION(UINT64 *offset, BYTE *blob, TCPA_PCR_SELECTION *pcr)
397 {
398 	UINT16 i;
399 
400 	Trspi_LoadBlob_UINT16(offset, pcr->sizeOfSelect, blob);
401 	for (i = 0; i < pcr->sizeOfSelect; i++)
402 		Trspi_LoadBlob_BYTE(offset, pcr->pcrSelect[i], blob);
403 }
404 
405 void
406 Trspi_LoadBlob_KEY12(UINT64 *offset, BYTE *blob, TPM_KEY12 *key)
407 {
408 	Trspi_LoadBlob_UINT16(offset, key->tag, blob);
409 	Trspi_LoadBlob_UINT16(offset, key->fill, blob);
410 	Trspi_LoadBlob_UINT16(offset, key->keyUsage, blob);
411 	Trspi_LoadBlob_KEY_FLAGS(offset, blob, &key->keyFlags);
412 	Trspi_LoadBlob_BYTE(offset, key->authDataUsage, blob);
413 	Trspi_LoadBlob_KEY_PARMS(offset, blob, &key->algorithmParms);
414 	Trspi_LoadBlob_UINT32(offset, key->PCRInfoSize, blob);
415 	Trspi_LoadBlob(offset, key->PCRInfoSize, blob, key->PCRInfo);
416 	Trspi_LoadBlob_STORE_PUBKEY(offset, blob, &key->pubKey);
417 	Trspi_LoadBlob_UINT32(offset, key->encSize, blob);
418 	Trspi_LoadBlob(offset, key->encSize, blob, key->encData);
419 }
420 
421 void
422 Trspi_LoadBlob_KEY(UINT64 *offset, BYTE *blob, TCPA_KEY *key)
423 {
424 	Trspi_LoadBlob_TCPA_VERSION(offset, blob, key->ver);
425 	Trspi_LoadBlob_UINT16(offset, key->keyUsage, blob);
426 	Trspi_LoadBlob_KEY_FLAGS(offset, blob, &key->keyFlags);
427 	Trspi_LoadBlob_BYTE(offset, key->authDataUsage, blob);
428 	Trspi_LoadBlob_KEY_PARMS(offset, blob, &key->algorithmParms);
429 	Trspi_LoadBlob_UINT32(offset, key->PCRInfoSize, blob);
430 	Trspi_LoadBlob(offset, key->PCRInfoSize, blob, key->PCRInfo);
431 	Trspi_LoadBlob_STORE_PUBKEY(offset, blob, &key->pubKey);
432 	Trspi_LoadBlob_UINT32(offset, key->encSize, blob);
433 	Trspi_LoadBlob(offset, key->encSize, blob, key->encData);
434 }
435 
436 void
437 Trspi_LoadBlob_KEY_FLAGS(UINT64 *offset, BYTE *blob, TCPA_KEY_FLAGS *flags)
438 {
439 	Trspi_LoadBlob_UINT32(offset, *flags, blob);
440 }
441 
442 void
443 Trspi_UnloadBlob_KEY_FLAGS(UINT64 *offset, BYTE *blob, TCPA_KEY_FLAGS *flags)
444 {
445 	Trspi_UnloadBlob_UINT32(offset, flags, blob);
446 }
447 
448 void
449 Trspi_LoadBlob_KEY_PARMS(UINT64 *offset, BYTE *blob, TCPA_KEY_PARMS *keyInfo)
450 {
451 	Trspi_LoadBlob_UINT32(offset, keyInfo->algorithmID, blob);
452 	Trspi_LoadBlob_UINT16(offset, keyInfo->encScheme, blob);
453 	Trspi_LoadBlob_UINT16(offset, keyInfo->sigScheme, blob);
454 	Trspi_LoadBlob_UINT32(offset, keyInfo->parmSize, blob);
455 
456 	if (keyInfo->parmSize > 0)
457 		Trspi_LoadBlob(offset, keyInfo->parmSize, blob, keyInfo->parms);
458 }
459 
460 void
461 Trspi_LoadBlob_STORE_PUBKEY(UINT64 *offset, BYTE *blob, TCPA_STORE_PUBKEY *store)
462 {
463 	Trspi_LoadBlob_UINT32(offset, store->keyLength, blob);
464 	Trspi_LoadBlob(offset, store->keyLength, blob, store->key);
465 }
466 
467 void
468 Trspi_LoadBlob_UUID(UINT64 *offset, BYTE *blob, TSS_UUID uuid)
469 {
470 	Trspi_LoadBlob_UINT32(offset, uuid.ulTimeLow, blob);
471 	Trspi_LoadBlob_UINT16(offset, uuid.usTimeMid, blob);
472 	Trspi_LoadBlob_UINT16(offset, uuid.usTimeHigh, blob);
473 	Trspi_LoadBlob_BYTE(offset, uuid.bClockSeqHigh, blob);
474 	Trspi_LoadBlob_BYTE(offset, uuid.bClockSeqLow, blob);
475 	Trspi_LoadBlob(offset, 6, blob, uuid.rgbNode);
476 }
477 
478 void
479 Trspi_UnloadBlob_UUID(UINT64 *offset, BYTE *blob, TSS_UUID *uuid)
480 {
481 	if (!uuid) {
482 		Trspi_UnloadBlob_UINT32(offset, NULL, blob);
483 		Trspi_UnloadBlob_UINT16(offset, NULL, blob);
484 		Trspi_UnloadBlob_UINT16(offset, NULL, blob);
485 		Trspi_UnloadBlob_BYTE(offset, NULL, blob);
486 		Trspi_UnloadBlob_BYTE(offset, NULL, blob);
487 		Trspi_UnloadBlob(offset, 6, blob, NULL);
488 
489 		return;
490 	}
491 
492 	memset(uuid, 0, sizeof(TSS_UUID));
493 	Trspi_UnloadBlob_UINT32(offset, &uuid->ulTimeLow, blob);
494 	Trspi_UnloadBlob_UINT16(offset, &uuid->usTimeMid, blob);
495 	Trspi_UnloadBlob_UINT16(offset, &uuid->usTimeHigh, blob);
496 	Trspi_UnloadBlob_BYTE(offset, &uuid->bClockSeqHigh, blob);
497 	Trspi_UnloadBlob_BYTE(offset, &uuid->bClockSeqLow, blob);
498 	Trspi_UnloadBlob(offset, 6, blob, uuid->rgbNode);
499 }
500 
501 TSS_RESULT
502 Trspi_UnloadBlob_KEY_PARMS(UINT64 *offset, BYTE *blob, TCPA_KEY_PARMS *keyParms)
503 {
504 	if (!keyParms) {
505 		UINT32 parmSize;
506 
507 		Trspi_UnloadBlob_UINT32(offset, NULL, blob);
508 		Trspi_UnloadBlob_UINT16(offset, NULL, blob);
509 		Trspi_UnloadBlob_UINT16(offset, NULL, blob);
510 		Trspi_UnloadBlob_UINT32(offset, &parmSize, blob);
511 
512 		(*offset) += parmSize;
513 
514 		return TSS_SUCCESS;
515 	}
516 
517 	Trspi_UnloadBlob_UINT32(offset, &keyParms->algorithmID, blob);
518 	Trspi_UnloadBlob_UINT16(offset, &keyParms->encScheme, blob);
519 	Trspi_UnloadBlob_UINT16(offset, &keyParms->sigScheme, blob);
520 	Trspi_UnloadBlob_UINT32(offset, &keyParms->parmSize, blob);
521 
522 	if (keyParms->parmSize > 0) {
523 		keyParms->parms = malloc(keyParms->parmSize);
524 		if (keyParms->parms == NULL) {
525 			LogError("malloc of %u bytes failed.", keyParms->parmSize);
526 			return TSPERR(TSS_E_OUTOFMEMORY);
527 		}
528 		Trspi_UnloadBlob(offset, keyParms->parmSize, blob, keyParms->parms);
529 	} else {
530 		keyParms->parms = NULL;
531 	}
532 
533 	return TSS_SUCCESS;
534 }
535 
536 TSS_RESULT
537 Trspi_UnloadBlob_KEY12(UINT64 *offset, BYTE *blob, TPM_KEY12 *key)
538 {
539 	TSS_RESULT result;
540 
541 	if (!key) {
542 		UINT32 PCRInfoSize, encSize;
543 
544 		Trspi_UnloadBlob_UINT16(offset, NULL, blob);
545 		Trspi_UnloadBlob_UINT16(offset, NULL, blob);
546 		Trspi_UnloadBlob_UINT16(offset, NULL, blob);
547 		Trspi_UnloadBlob_KEY_FLAGS(offset, blob, NULL);
548 		Trspi_UnloadBlob_BYTE(offset, NULL, blob);
549 		Trspi_UnloadBlob_KEY_PARMS(offset, blob, NULL);
550 		Trspi_UnloadBlob_UINT32(offset, &PCRInfoSize, blob);
551 		Trspi_UnloadBlob(offset, PCRInfoSize, blob, NULL);
552 		Trspi_UnloadBlob_STORE_PUBKEY(offset, blob, NULL);
553 		Trspi_UnloadBlob_UINT32(offset, &encSize, blob);
554 		Trspi_UnloadBlob(offset, encSize, blob, NULL);
555 
556 		return TSS_SUCCESS;
557 	}
558 
559 	Trspi_UnloadBlob_UINT16(offset, &key->tag, blob);
560 	Trspi_UnloadBlob_UINT16(offset, &key->fill, blob);
561 	Trspi_UnloadBlob_UINT16(offset, &key->keyUsage, blob);
562 	Trspi_UnloadBlob_KEY_FLAGS(offset, blob, &key->keyFlags);
563 	Trspi_UnloadBlob_BYTE(offset, &key->authDataUsage, blob);
564 	if ((result = Trspi_UnloadBlob_KEY_PARMS(offset, (BYTE *) blob, &key->algorithmParms)))
565 		return result;
566 	Trspi_UnloadBlob_UINT32(offset, &key->PCRInfoSize, blob);
567 
568 	if (key->PCRInfoSize > 0) {
569 		key->PCRInfo = malloc(key->PCRInfoSize);
570 		if (key->PCRInfo == NULL) {
571 			LogError("malloc of %d bytes failed.", key->PCRInfoSize);
572 			return TSPERR(TSS_E_OUTOFMEMORY);
573 		}
574 		Trspi_UnloadBlob(offset, key->PCRInfoSize, blob, key->PCRInfo);
575 	} else {
576 		key->PCRInfo = NULL;
577 	}
578 
579 	if ((result = Trspi_UnloadBlob_STORE_PUBKEY(offset, blob, &key->pubKey)))
580 		return result;
581 	Trspi_UnloadBlob_UINT32(offset, &key->encSize, blob);
582 
583 	if (key->encSize > 0) {
584 		key->encData = malloc(key->encSize);
585 		if (key->encData == NULL) {
586 			LogError("malloc of %d bytes failed.", key->encSize);
587 			return TSPERR(TSS_E_OUTOFMEMORY);
588 		}
589 		Trspi_UnloadBlob(offset, key->encSize, blob, key->encData);
590 	} else {
591 		key->encData = NULL;
592 	}
593 
594 	return result;
595 }
596 
597 TSS_RESULT
598 Trspi_UnloadBlob_KEY(UINT64 *offset, BYTE *blob, TCPA_KEY *key)
599 {
600 	TSS_RESULT result;
601 
602 	if (!key) {
603 		UINT32 PCRInfoSize, encSize;
604 
605 		Trspi_UnloadBlob_TCPA_VERSION(offset, blob, NULL);
606 		Trspi_UnloadBlob_UINT16(offset, NULL, blob);
607 		Trspi_UnloadBlob_KEY_FLAGS(offset, blob, NULL);
608 		Trspi_UnloadBlob_BYTE(offset, NULL, blob);
609 		Trspi_UnloadBlob_KEY_PARMS(offset, blob, NULL);
610 		Trspi_UnloadBlob_UINT32(offset, &PCRInfoSize, blob);
611 		Trspi_UnloadBlob(offset, PCRInfoSize, blob, NULL);
612 		Trspi_UnloadBlob_STORE_PUBKEY(offset, blob, NULL);
613 		Trspi_UnloadBlob_UINT32(offset, &encSize, blob);
614 		Trspi_UnloadBlob(offset, encSize, blob, NULL);
615 
616 		return TSS_SUCCESS;
617 	}
618 
619 	Trspi_UnloadBlob_TCPA_VERSION(offset, blob, &key->ver);
620 	Trspi_UnloadBlob_UINT16(offset, &key->keyUsage, blob);
621 	Trspi_UnloadBlob_KEY_FLAGS(offset, blob, &key->keyFlags);
622 	Trspi_UnloadBlob_BYTE(offset, &key->authDataUsage, blob);
623 	if ((result = Trspi_UnloadBlob_KEY_PARMS(offset, (BYTE *) blob, &key->algorithmParms)))
624 		return result;
625 	Trspi_UnloadBlob_UINT32(offset, &key->PCRInfoSize, blob);
626 
627 	if (key->PCRInfoSize > 0) {
628 		key->PCRInfo = malloc(key->PCRInfoSize);
629 		if (key->PCRInfo == NULL) {
630 			LogError("malloc of %d bytes failed.", key->PCRInfoSize);
631 			return TSPERR(TSS_E_OUTOFMEMORY);
632 		}
633 		Trspi_UnloadBlob(offset, key->PCRInfoSize, blob, key->PCRInfo);
634 	} else {
635 		key->PCRInfo = NULL;
636 	}
637 
638 	if ((result = Trspi_UnloadBlob_STORE_PUBKEY(offset, blob, &key->pubKey)))
639 		return result;
640 	Trspi_UnloadBlob_UINT32(offset, &key->encSize, blob);
641 
642 	if (key->encSize > 0) {
643 		key->encData = malloc(key->encSize);
644 		if (key->encData == NULL) {
645 			LogError("malloc of %d bytes failed.", key->encSize);
646 			return TSPERR(TSS_E_OUTOFMEMORY);
647 		}
648 		Trspi_UnloadBlob(offset, key->encSize, blob, key->encData);
649 	} else {
650 		key->encData = NULL;
651 	}
652 
653 	return result;
654 }
655 
656 TSS_RESULT
657 Trspi_UnloadBlob_STORE_PUBKEY(UINT64 *offset, BYTE *blob, TCPA_STORE_PUBKEY *store)
658 {
659 	if (!store) {
660 		UINT32 keyLength;
661 
662 		Trspi_UnloadBlob_UINT32(offset, &keyLength, blob);
663 		Trspi_UnloadBlob(offset, keyLength, blob, NULL);
664 
665 		return TSS_SUCCESS;
666 	}
667 
668 	Trspi_UnloadBlob_UINT32(offset, &store->keyLength, blob);
669 
670 	if (store->keyLength > 0) {
671 		store->key = malloc(store->keyLength);
672 		if (store->key == NULL) {
673 			LogError("malloc of %d bytes failed.", store->keyLength);
674 			return TSPERR(TSS_E_OUTOFMEMORY);
675 		}
676 		Trspi_UnloadBlob(offset, store->keyLength, blob, store->key);
677 	} else {
678 		store->key = NULL;
679 	}
680 
681 	return TSS_SUCCESS;
682 }
683 
684 void
685 Trspi_UnloadBlob_VERSION(UINT64 *offset, BYTE *blob, TCPA_VERSION *out)
686 {
687 	if (!out) {
688 		Trspi_UnloadBlob_BYTE(offset, NULL, blob);
689 		Trspi_UnloadBlob_BYTE(offset, NULL, blob);
690 		Trspi_UnloadBlob_BYTE(offset, NULL, blob);
691 		Trspi_UnloadBlob_BYTE(offset, NULL, blob);
692 
693 		return;
694 	}
695 
696 	Trspi_UnloadBlob_BYTE(offset, &out->major, blob);
697 	Trspi_UnloadBlob_BYTE(offset, &out->minor, blob);
698 	Trspi_UnloadBlob_BYTE(offset, &out->revMajor, blob);
699 	Trspi_UnloadBlob_BYTE(offset, &out->revMinor, blob);
700 }
701 
702 TSS_RESULT
703 Trspi_UnloadBlob_KM_KEYINFO(UINT64 *offset, BYTE *blob, TSS_KM_KEYINFO *info)
704 {
705 	if (!info) {
706 		UINT32 ulVendorDataLength;
707 
708 		Trspi_UnloadBlob_TSS_VERSION(offset, blob, NULL);
709 		Trspi_UnloadBlob_UUID(offset, blob, NULL);
710 		Trspi_UnloadBlob_UUID(offset, blob, NULL);
711 		Trspi_UnloadBlob_BYTE(offset, NULL, blob);
712 		Trspi_UnloadBlob_BOOL(offset, NULL, blob);
713 		Trspi_UnloadBlob_UINT32(offset, &ulVendorDataLength, blob);
714 
715 		(*offset) += ulVendorDataLength;
716 
717 		return TSS_SUCCESS;
718 	}
719 
720 	Trspi_UnloadBlob_TSS_VERSION(offset, blob, &info->versionInfo);
721 	Trspi_UnloadBlob_UUID(offset, blob, &info->keyUUID);
722 	Trspi_UnloadBlob_UUID(offset, blob, &info->parentKeyUUID);
723 	Trspi_UnloadBlob_BYTE(offset, &info->bAuthDataUsage, blob);
724 	Trspi_UnloadBlob_BOOL(offset, &info->fIsLoaded, blob);
725 	Trspi_UnloadBlob_UINT32(offset, &info->ulVendorDataLength, blob);
726 	if (info->ulVendorDataLength > 0){
727 		/* allocate space for vendor data */
728 		info->rgbVendorData = malloc(info->ulVendorDataLength);
729 		if (info->rgbVendorData == NULL) {
730 			LogError("malloc of %u bytes failed.", info->ulVendorDataLength);
731 			return TSPERR(TSS_E_OUTOFMEMORY);
732 		}
733 
734 		Trspi_UnloadBlob(offset, info->ulVendorDataLength, blob, info->rgbVendorData);
735 	} else
736 		info->rgbVendorData = NULL;
737 
738 	return TSS_SUCCESS;
739 }
740 
741 TSS_RESULT
742 Trspi_UnloadBlob_KM_KEYINFO2(UINT64 *offset, BYTE *blob, TSS_KM_KEYINFO2 *info)
743 {
744 	if (!info) {
745 		UINT32 ulVendorDataLength;
746 
747 		Trspi_UnloadBlob_TSS_VERSION(offset, blob, NULL);
748 		Trspi_UnloadBlob_UUID(offset, blob, NULL);
749 		Trspi_UnloadBlob_UUID(offset, blob, NULL);
750 		Trspi_UnloadBlob_BYTE(offset, NULL, blob);
751 		Trspi_UnloadBlob_UINT32(offset, NULL, blob);
752 		Trspi_UnloadBlob_UINT32(offset, NULL, blob);
753 		Trspi_UnloadBlob_BOOL(offset, NULL, blob);
754 		Trspi_UnloadBlob_UINT32(offset, &ulVendorDataLength, blob);
755 
756 		(*offset) += ulVendorDataLength;
757 
758 		return TSS_SUCCESS;
759 	}
760 
761 	Trspi_UnloadBlob_TSS_VERSION(offset, blob, &info->versionInfo);
762 	Trspi_UnloadBlob_UUID(offset, blob, &info->keyUUID);
763 	Trspi_UnloadBlob_UUID(offset, blob, &info->parentKeyUUID);
764 	Trspi_UnloadBlob_BYTE(offset, &info->bAuthDataUsage, blob);
765 	/* Takes data regarding the new 2 fields of TSS_KM_KEYINFO2 */
766 	Trspi_UnloadBlob_UINT32(offset, &info->persistentStorageType, blob);
767 	Trspi_UnloadBlob_UINT32(offset, &info->persistentStorageTypeParent, blob);
768 	Trspi_UnloadBlob_BOOL(offset, &info->fIsLoaded, blob);
769 	Trspi_UnloadBlob_UINT32(offset, &info->ulVendorDataLength, blob);
770 	if (info->ulVendorDataLength > 0) {
771 		/* allocate space for vendor data */
772 		info->rgbVendorData = malloc(info->ulVendorDataLength);
773 		if (info->rgbVendorData == NULL) {
774 			LogError("malloc of %u bytes failed.", info->ulVendorDataLength);
775 			return TSPERR(TSS_E_OUTOFMEMORY);
776 		}
777 
778 		Trspi_UnloadBlob(offset, info->ulVendorDataLength, blob, info->rgbVendorData);
779 	} else
780 		info->rgbVendorData = NULL;
781 
782 	return TSS_SUCCESS;
783 }
784 
785 void
786 Trspi_LoadBlob_PCR_EVENT(UINT64 *offset, BYTE *blob, TSS_PCR_EVENT *event)
787 {
788 	Trspi_LoadBlob_TCPA_VERSION(offset, blob, *(TCPA_VERSION *)(&event->versionInfo));
789 	Trspi_LoadBlob_UINT32(offset, event->ulPcrIndex, blob);
790 	Trspi_LoadBlob_UINT32(offset, event->eventType, blob);
791 
792 	Trspi_LoadBlob_UINT32(offset, event->ulPcrValueLength, blob);
793 	if (event->ulPcrValueLength > 0)
794 		Trspi_LoadBlob(offset, event->ulPcrValueLength, blob, event->rgbPcrValue);
795 
796 	Trspi_LoadBlob_UINT32(offset, event->ulEventLength, blob);
797 	if (event->ulEventLength > 0)
798 		Trspi_LoadBlob(offset, event->ulEventLength, blob, event->rgbEvent);
799 
800 }
801 
802 TSS_RESULT
803 Trspi_UnloadBlob_PCR_EVENT(UINT64 *offset, BYTE *blob, TSS_PCR_EVENT *event)
804 {
805 	if (!event) {
806 		UINT32 ulPcrValueLength, ulEventLength;
807 
808 		Trspi_UnloadBlob_VERSION(offset, blob, NULL);
809 		Trspi_UnloadBlob_UINT32(offset, NULL, blob);
810 		Trspi_UnloadBlob_UINT32(offset, NULL, blob);
811 
812 		Trspi_UnloadBlob_UINT32(offset, &ulPcrValueLength, blob);
813 		(*offset) += ulPcrValueLength;
814 
815 		Trspi_UnloadBlob_UINT32(offset, &ulEventLength, blob);
816 		(*offset) += ulEventLength;
817 
818 		return TSS_SUCCESS;
819 	}
820 
821 	Trspi_UnloadBlob_VERSION(offset, blob, (TCPA_VERSION *)&(event->versionInfo));
822 	Trspi_UnloadBlob_UINT32(offset, &event->ulPcrIndex, blob);
823 	Trspi_UnloadBlob_UINT32(offset, &event->eventType, blob);
824 
825 	Trspi_UnloadBlob_UINT32(offset, &event->ulPcrValueLength, blob);
826 	if (event->ulPcrValueLength > 0) {
827 		event->rgbPcrValue = malloc(event->ulPcrValueLength);
828 		if (event->rgbPcrValue == NULL) {
829 			LogError("malloc of %u bytes failed.", event->ulPcrValueLength);
830 			return TSPERR(TSS_E_OUTOFMEMORY);
831 		}
832 
833 		Trspi_UnloadBlob(offset, event->ulPcrValueLength, blob, event->rgbPcrValue);
834 	} else {
835 		event->rgbPcrValue = NULL;
836 	}
837 
838 	Trspi_UnloadBlob_UINT32(offset, &event->ulEventLength, blob);
839 	if (event->ulEventLength > 0) {
840 		event->rgbEvent = malloc(event->ulEventLength);
841 		if (event->rgbEvent == NULL) {
842 			LogError("malloc of %d bytes failed.", event->ulEventLength);
843 			return TSPERR(TSS_E_OUTOFMEMORY);
844 		}
845 
846 		Trspi_UnloadBlob(offset, event->ulEventLength, blob, event->rgbEvent);
847 	} else {
848 		event->rgbEvent = NULL;
849 	}
850 
851 	return TSS_SUCCESS;
852 }
853 
854 /* loads a blob with the info needed to hash when creating the private key area
855  * of a TPM_KEY(12) from an external source
856  */
857 void
858 Trspi_LoadBlob_PRIVKEY_DIGEST12(UINT64 *offset, BYTE *blob, TPM_KEY12 *key)
859 {
860 	Trspi_LoadBlob_UINT16(offset, key->tag, blob);
861 	Trspi_LoadBlob_UINT16(offset, key->fill, blob);
862 	Trspi_LoadBlob_UINT16(offset, key->keyUsage, blob);
863 	Trspi_LoadBlob_KEY_FLAGS(offset, blob, &key->keyFlags);
864 	Trspi_LoadBlob_BYTE(offset, key->authDataUsage, blob);
865 	Trspi_LoadBlob_KEY_PARMS(offset, blob, &key->algorithmParms);
866 
867 	Trspi_LoadBlob_UINT32(offset, key->PCRInfoSize, blob);
868 	/* exclude pcrInfo when PCRInfoSize is 0 as spec'd in TPM 1.1b spec p.71 */
869 	if (key->PCRInfoSize != 0)
870 		Trspi_LoadBlob(offset, key->PCRInfoSize, blob, key->PCRInfo);
871 
872 	Trspi_LoadBlob_STORE_PUBKEY(offset, blob, &key->pubKey);
873 	/* exclude encSize, encData as spec'd in TPM 1.1b spec p.71 */
874 }
875 
876 void
877 Trspi_LoadBlob_PRIVKEY_DIGEST(UINT64 *offset, BYTE *blob, TCPA_KEY *key)
878 {
879 	Trspi_LoadBlob_TCPA_VERSION(offset, blob, key->ver);
880 	Trspi_LoadBlob_UINT16(offset, key->keyUsage, blob);
881 	Trspi_LoadBlob_KEY_FLAGS(offset, blob, &key->keyFlags);
882 	Trspi_LoadBlob_BYTE(offset, key->authDataUsage, blob);
883 	Trspi_LoadBlob_KEY_PARMS(offset, blob, &key->algorithmParms);
884 
885 	Trspi_LoadBlob_UINT32(offset, key->PCRInfoSize, blob);
886 	/* exclude pcrInfo when PCRInfoSize is 0 as spec'd in TPM 1.1b spec p.71 */
887 	if (key->PCRInfoSize != 0)
888 		Trspi_LoadBlob(offset, key->PCRInfoSize, blob, key->PCRInfo);
889 
890 	Trspi_LoadBlob_STORE_PUBKEY(offset, blob, &key->pubKey);
891 	/* exclude encSize, encData as spec'd in TPM 1.1b spec p.71 */
892 }
893 
894 void
895 Trspi_LoadBlob_SYMMETRIC_KEY(UINT64 *offset, BYTE *blob, TCPA_SYMMETRIC_KEY *key)
896 {
897 	Trspi_LoadBlob_UINT32(offset, key->algId, blob);
898 	Trspi_LoadBlob_UINT16(offset, key->encScheme, blob);
899 	Trspi_LoadBlob_UINT16(offset, key->size, blob);
900 
901 	if (key->size > 0)
902 		Trspi_LoadBlob(offset, key->size, blob, key->data);
903 }
904 
905 TSS_RESULT
906 Trspi_UnloadBlob_SYMMETRIC_KEY(UINT64 *offset, BYTE *blob, TCPA_SYMMETRIC_KEY *key)
907 {
908 	if (!key) {
909 		UINT16 size;
910 
911 		Trspi_UnloadBlob_UINT32(offset, NULL, blob);
912 		Trspi_UnloadBlob_UINT16(offset, NULL, blob);
913 		Trspi_UnloadBlob_UINT16(offset, &size, blob);
914 		(*offset) += size;
915 
916 		return TSS_SUCCESS;
917 	}
918 
919 	Trspi_UnloadBlob_UINT32(offset, &key->algId, blob);
920 	Trspi_UnloadBlob_UINT16(offset, &key->encScheme, blob);
921 	Trspi_UnloadBlob_UINT16(offset, &key->size, blob);
922 
923 	if (key->size > 0) {
924 		key->data = malloc(key->size);
925 		if (key->data == NULL) {
926 			key->size = 0;
927 			return TSPERR(TSS_E_OUTOFMEMORY);
928 		}
929 		Trspi_UnloadBlob(offset, key->size, blob, key->data);
930 	} else {
931 		key->data = NULL;
932 	}
933 
934 	return TSS_SUCCESS;
935 }
936 
937 void
938 Trspi_LoadBlob_IDENTITY_REQ(UINT64 *offset, BYTE *blob, TCPA_IDENTITY_REQ *req)
939 {
940 	Trspi_LoadBlob_UINT32(offset, req->asymSize, blob);
941 	Trspi_LoadBlob_UINT32(offset, req->symSize, blob);
942 	Trspi_LoadBlob_KEY_PARMS(offset, blob, &req->asymAlgorithm);
943 	Trspi_LoadBlob_KEY_PARMS(offset, blob, &req->symAlgorithm);
944 	Trspi_LoadBlob(offset, req->asymSize, blob, req->asymBlob);
945 	Trspi_LoadBlob(offset, req->symSize, blob, req->symBlob);
946 }
947 
948 void
949 Trspi_LoadBlob_CHANGEAUTH_VALIDATE(UINT64 *offset, BYTE *blob, TPM_CHANGEAUTH_VALIDATE *caValidate)
950 {
951 	Trspi_LoadBlob(offset, TCPA_SHA1_160_HASH_LEN, blob, caValidate->newAuthSecret.authdata);
952 	Trspi_LoadBlob(offset, TCPA_SHA1_160_HASH_LEN, blob, caValidate->n1.nonce);
953 }
954 
955 TSS_RESULT
956 Trspi_UnloadBlob_IDENTITY_REQ(UINT64 *offset, BYTE *blob, TCPA_IDENTITY_REQ *req)
957 {
958 	TSS_RESULT result;
959 
960 	if (!req) {
961 		UINT32 asymSize, symSize;
962 
963 		Trspi_UnloadBlob_UINT32(offset, &asymSize, blob);
964 		Trspi_UnloadBlob_UINT32(offset, &symSize, blob);
965 		(void)Trspi_UnloadBlob_KEY_PARMS(offset, blob, NULL);
966 		(void)Trspi_UnloadBlob_KEY_PARMS(offset, blob, NULL);
967 
968 		(*offset) += asymSize;
969 		(*offset) += symSize;
970 
971 		return TSS_SUCCESS;
972 	}
973 
974 	Trspi_UnloadBlob_UINT32(offset, &req->asymSize, blob);
975 	Trspi_UnloadBlob_UINT32(offset, &req->symSize, blob);
976 	if ((result = Trspi_UnloadBlob_KEY_PARMS(offset, blob, &req->asymAlgorithm)))
977 		return result;
978 	if ((Trspi_UnloadBlob_KEY_PARMS(offset, blob, &req->symAlgorithm))) {
979 		free(req->asymAlgorithm.parms);
980 		req->asymAlgorithm.parmSize = 0;
981 		return result;
982 	}
983 
984 	if (req->asymSize > 0) {
985 		req->asymBlob = malloc(req->asymSize);
986 		if (req->asymBlob == NULL) {
987 			req->asymSize = 0;
988 			req->asymAlgorithm.parmSize = 0;
989 			free(req->asymAlgorithm.parms);
990 			req->symAlgorithm.parmSize = 0;
991 			free(req->symAlgorithm.parms);
992 			return TSPERR(TSS_E_OUTOFMEMORY);
993 		}
994 		Trspi_UnloadBlob(offset, req->asymSize, blob, req->asymBlob);
995 	} else {
996 		req->asymBlob = NULL;
997 	}
998 
999 	if (req->symSize > 0) {
1000 		req->symBlob = malloc(req->symSize);
1001 		if (req->symBlob == NULL) {
1002 			req->symSize = 0;
1003 			req->asymSize = 0;
1004 			free(req->asymBlob);
1005 			req->asymBlob = NULL;
1006 			req->asymAlgorithm.parmSize = 0;
1007 			free(req->asymAlgorithm.parms);
1008 			req->symAlgorithm.parmSize = 0;
1009 			free(req->symAlgorithm.parms);
1010 			return TSPERR(TSS_E_OUTOFMEMORY);
1011 		}
1012 		Trspi_UnloadBlob(offset, req->symSize, blob, req->symBlob);
1013 	} else {
1014 		req->symBlob = NULL;
1015 	}
1016 
1017 	return TSS_SUCCESS;
1018 }
1019 
1020 TSS_RESULT
1021 Trspi_UnloadBlob_IDENTITY_PROOF(UINT64 *offset, BYTE *blob, TCPA_IDENTITY_PROOF *proof)
1022 {
1023 	TSS_RESULT result;
1024 
1025 	if (!proof) {
1026 		UINT32 labelSize, identityBindingSize, endorsementSize, platformSize;
1027 		UINT32 conformanceSize;
1028 
1029 		Trspi_UnloadBlob_VERSION(offset, blob, NULL);
1030 		Trspi_UnloadBlob_UINT32(offset, &labelSize, blob);
1031 		Trspi_UnloadBlob_UINT32(offset, &identityBindingSize, blob);
1032 		Trspi_UnloadBlob_UINT32(offset, &endorsementSize, blob);
1033 		Trspi_UnloadBlob_UINT32(offset, &platformSize, blob);
1034 		Trspi_UnloadBlob_UINT32(offset, &conformanceSize, blob);
1035 
1036 		(void)Trspi_UnloadBlob_PUBKEY(offset, blob, NULL);
1037 
1038 		(*offset) += labelSize;
1039 		(*offset) += identityBindingSize;
1040 		(*offset) += endorsementSize;
1041 		(*offset) += platformSize;
1042 		(*offset) += conformanceSize;
1043 
1044 		return TSS_SUCCESS;
1045 	}
1046 
1047 	/* helps when an error occurs */
1048 	memset(proof, 0, sizeof(TCPA_IDENTITY_PROOF));
1049 
1050 	Trspi_UnloadBlob_VERSION(offset, blob, (TCPA_VERSION *)&proof->ver);
1051 	Trspi_UnloadBlob_UINT32(offset, &proof->labelSize, blob);
1052 	Trspi_UnloadBlob_UINT32(offset, &proof->identityBindingSize, blob);
1053 	Trspi_UnloadBlob_UINT32(offset, &proof->endorsementSize, blob);
1054 	Trspi_UnloadBlob_UINT32(offset, &proof->platformSize, blob);
1055 	Trspi_UnloadBlob_UINT32(offset, &proof->conformanceSize, blob);
1056 
1057 	if ((result = Trspi_UnloadBlob_PUBKEY(offset, blob,
1058 					      &proof->identityKey))) {
1059 		proof->labelSize = 0;
1060 		proof->identityBindingSize = 0;
1061 		proof->endorsementSize = 0;
1062 		proof->platformSize = 0;
1063 		proof->conformanceSize = 0;
1064 		return result;
1065 	}
1066 
1067 	if (proof->labelSize > 0) {
1068 		proof->labelArea = malloc(proof->labelSize);
1069 		if (proof->labelArea == NULL) {
1070 			result = TSPERR(TSS_E_OUTOFMEMORY);
1071 			goto error;
1072 		}
1073 		Trspi_UnloadBlob(offset, proof->labelSize, blob, proof->labelArea);
1074 	} else {
1075 		proof->labelArea = NULL;
1076 	}
1077 
1078 	if (proof->identityBindingSize > 0) {
1079 		proof->identityBinding = malloc(proof->identityBindingSize);
1080 		if (proof->identityBinding == NULL) {
1081 			result = TSPERR(TSS_E_OUTOFMEMORY);
1082 			goto error;
1083 		}
1084 		Trspi_UnloadBlob(offset, proof->identityBindingSize, blob,
1085 				 proof->identityBinding);
1086 	} else {
1087 		proof->identityBinding = NULL;
1088 	}
1089 
1090 	if (proof->endorsementSize > 0) {
1091 		proof->endorsementCredential = malloc(proof->endorsementSize);
1092 		if (proof->endorsementCredential == NULL) {
1093 			result = TSPERR(TSS_E_OUTOFMEMORY);
1094 			goto error;
1095 		}
1096 		Trspi_UnloadBlob(offset, proof->endorsementSize, blob,
1097 				 proof->endorsementCredential);
1098 	} else {
1099 		proof->endorsementCredential = NULL;
1100 	}
1101 
1102 	if (proof->platformSize > 0) {
1103 		proof->platformCredential = malloc(proof->platformSize);
1104 		if (proof->platformCredential == NULL) {
1105 			result = TSPERR(TSS_E_OUTOFMEMORY);
1106 			goto error;
1107 		}
1108 		Trspi_UnloadBlob(offset, proof->platformSize, blob,
1109 				 proof->platformCredential);
1110 	} else {
1111 		proof->platformCredential = NULL;
1112 	}
1113 
1114 	if (proof->conformanceSize > 0) {
1115 		proof->conformanceCredential = malloc(proof->conformanceSize);
1116 		if (proof->conformanceCredential == NULL) {
1117 			result = TSPERR(TSS_E_OUTOFMEMORY);
1118 			goto error;
1119 		}
1120 		Trspi_UnloadBlob(offset, proof->conformanceSize, blob,
1121 				 proof->conformanceCredential);
1122 	} else {
1123 		proof->conformanceCredential = NULL;
1124 	}
1125 
1126 	return TSS_SUCCESS;
1127 error:
1128 	proof->labelSize = 0;
1129 	proof->identityBindingSize = 0;
1130 	proof->endorsementSize = 0;
1131 	proof->platformSize = 0;
1132 	proof->conformanceSize = 0;
1133 	free(proof->labelArea);
1134 	proof->labelArea = NULL;
1135 	free(proof->identityBinding);
1136 	proof->identityBinding = NULL;
1137 	free(proof->endorsementCredential);
1138 	proof->endorsementCredential = NULL;
1139 	free(proof->conformanceCredential);
1140 	proof->conformanceCredential = NULL;
1141 	/* free identityKey */
1142 	free(proof->identityKey.pubKey.key);
1143 	free(proof->identityKey.algorithmParms.parms);
1144 	proof->identityKey.pubKey.key = NULL;
1145 	proof->identityKey.pubKey.keyLength = 0;
1146 	proof->identityKey.algorithmParms.parms = NULL;
1147 	proof->identityKey.algorithmParms.parmSize = 0;
1148 
1149 	return result;
1150 }
1151 
1152 void
1153 Trspi_LoadBlob_SYM_CA_ATTESTATION(UINT64 *offset, BYTE *blob, TCPA_SYM_CA_ATTESTATION *sym)
1154 {
1155 	Trspi_LoadBlob_UINT32(offset, sym->credSize, blob);
1156 	Trspi_LoadBlob_KEY_PARMS(offset, blob, &sym->algorithm);
1157 	Trspi_LoadBlob(offset, sym->credSize, blob, sym->credential);
1158 }
1159 
1160 TSS_RESULT
1161 Trspi_UnloadBlob_SYM_CA_ATTESTATION(UINT64 *offset, BYTE *blob, TCPA_SYM_CA_ATTESTATION *sym)
1162 {
1163 	TSS_RESULT result;
1164 
1165 	if (!sym) {
1166 		UINT32 credSize;
1167 
1168 		Trspi_UnloadBlob_UINT32(offset, &credSize, blob);
1169 		(void)Trspi_UnloadBlob_KEY_PARMS(offset, blob, NULL);
1170 
1171 		(*offset) += credSize;
1172 
1173 		return TSS_SUCCESS;
1174 	}
1175 
1176 	Trspi_UnloadBlob_UINT32(offset, &sym->credSize, blob);
1177 	if ((result = Trspi_UnloadBlob_KEY_PARMS(offset, blob, &sym->algorithm))) {
1178 		sym->credSize = 0;
1179 		return result;
1180 	}
1181 
1182 	if (sym->credSize > 0) {
1183 		if ((sym->credential = malloc(sym->credSize)) == NULL) {
1184 			free(sym->algorithm.parms);
1185 			sym->algorithm.parmSize = 0;
1186 			sym->credSize = 0;
1187 			return TSPERR(TSS_E_OUTOFMEMORY);
1188 		}
1189 		Trspi_UnloadBlob(offset, sym->credSize, blob, sym->credential);
1190 	} else {
1191 		sym->credential = NULL;
1192 	}
1193 
1194 	return TSS_SUCCESS;
1195 }
1196 
1197 void
1198 Trspi_LoadBlob_ASYM_CA_CONTENTS(UINT64 *offset, BYTE *blob, TCPA_ASYM_CA_CONTENTS *asym)
1199 {
1200 	Trspi_LoadBlob_SYMMETRIC_KEY(offset, blob, &asym->sessionKey);
1201 	Trspi_LoadBlob(offset, TCPA_SHA1_160_HASH_LEN, blob,
1202 		       (BYTE *)&asym->idDigest);
1203 }
1204 
1205 TSS_RESULT
1206 Trspi_UnloadBlob_ASYM_CA_CONTENTS(UINT64 *offset, BYTE *blob, TCPA_ASYM_CA_CONTENTS *asym)
1207 {
1208 	TSS_RESULT result;
1209 
1210 	if (!asym) {
1211 		(void)Trspi_UnloadBlob_SYMMETRIC_KEY(offset, blob, NULL);
1212 		Trspi_UnloadBlob(offset, TCPA_SHA1_160_HASH_LEN, blob, NULL);
1213 
1214 		return TSS_SUCCESS;
1215 	}
1216 
1217 	if ((result = Trspi_UnloadBlob_SYMMETRIC_KEY(offset, blob, &asym->sessionKey)))
1218 		return result;
1219 
1220 	Trspi_UnloadBlob(offset, TCPA_SHA1_160_HASH_LEN, blob, (BYTE *)&asym->idDigest);
1221 
1222 	return TSS_SUCCESS;
1223 }
1224 
1225 void
1226 Trspi_LoadBlob_BOUND_DATA(UINT64 *offset, TCPA_BOUND_DATA bd, UINT32 payloadLength, BYTE *blob)
1227 {
1228 	Trspi_LoadBlob_TCPA_VERSION(offset, blob, bd.ver);
1229 	Trspi_LoadBlob(offset, 1, blob, &bd.payload);
1230 	Trspi_LoadBlob(offset, payloadLength, blob, bd.payloadData);
1231 }
1232 
1233 /* function to mimic strerror with TSS error codes */
1234 char *
1235 Trspi_Error_String(TSS_RESULT r)
1236 {
1237 	/* Check the return code to see if it is common to all layers.
1238 	 * If so, return it.
1239 	 */
1240 	switch (TSS_ERROR_CODE(r)) {
1241 		case TSS_SUCCESS:			return "Success";
1242 		default:
1243 			break;
1244 	}
1245 
1246 	/* The return code is either unknown, or specific to a layer */
1247 	if (TSS_ERROR_LAYER(r) == TSS_LAYER_TPM) {
1248 		switch (TSS_ERROR_CODE(r)) {
1249 			case TPM_E_AUTHFAIL:			return "Authentication failed";
1250 			case TPM_E_BAD_PARAMETER:		return "Bad Parameter";
1251 			case TPM_E_BADINDEX:			return "Bad memory index";
1252 			case TPM_E_AUDITFAILURE:		return "Audit failure";
1253 			case TPM_E_CLEAR_DISABLED:		return "Clear has been disabled";
1254 			case TPM_E_DEACTIVATED:			return "TPM is deactivated";
1255 			case TPM_E_DISABLED:			return "TPM is disabled";
1256 			case TPM_E_FAIL:			return "Operation failed";
1257 			case TPM_E_BAD_ORDINAL:			return "Ordinal was unknown or inconsistent";
1258 			case TPM_E_INSTALL_DISABLED:		return "Owner install disabled";
1259 			case TPM_E_INVALID_KEYHANDLE:		return "Invalid keyhandle";
1260 			case TPM_E_KEYNOTFOUND:			return "Key not found";
1261 			case TPM_E_INAPPROPRIATE_ENC:		return "Bad encryption scheme";
1262 			case TPM_E_MIGRATEFAIL:			return "Migration authorization failed";
1263 			case TPM_E_INVALID_PCR_INFO:		return "PCR information uninterpretable";
1264 			case TPM_E_NOSPACE:			return "No space to load key";
1265 			case TPM_E_NOSRK:			return "No SRK";
1266 			case TPM_E_NOTSEALED_BLOB:		return "Encrypted blob invalid";
1267 			case TPM_E_OWNER_SET:			return "Owner already set";
1268 			case TPM_E_RESOURCES:			return "Insufficient TPM resources";
1269 			case TPM_E_SHORTRANDOM:			return "Random string too short";
1270 			case TPM_E_SIZE:			return "TPM out of space";
1271 			case TPM_E_WRONGPCRVAL:			return "Wrong PCR value";
1272 			case TPM_E_BAD_PARAM_SIZE:		return "Bad input size";
1273 			case TPM_E_SHA_THREAD:			return "No existing SHA-1 thread";
1274 			case TPM_E_SHA_ERROR:			return "SHA-1 error";
1275 			case TPM_E_FAILEDSELFTEST:		return "Self-test failed, TPM shutdown";
1276 			case TPM_E_AUTH2FAIL:			return "Second authorization session failed";
1277 			case TPM_E_BADTAG:			return "Invalid tag";
1278 			case TPM_E_IOERROR:			return "I/O error";
1279 			case TPM_E_ENCRYPT_ERROR:		return "Encryption error";
1280 			case TPM_E_DECRYPT_ERROR:		return "Decryption error";
1281 			case TPM_E_INVALID_AUTHHANDLE:		return "Invalid authorization handle";
1282 			case TPM_E_NO_ENDORSEMENT:		return "No EK";
1283 			case TPM_E_INVALID_KEYUSAGE:		return "Invalid key usage";
1284 			case TPM_E_WRONG_ENTITYTYPE:		return "Invalid entity type";
1285 			case TPM_E_INVALID_POSTINIT:		return "Invalid POST init sequence";
1286 			case TPM_E_INAPPROPRIATE_SIG:		return "Invalid signature format";
1287 			case TPM_E_BAD_KEY_PROPERTY:		return "Unsupported key parameters";
1288 			case TPM_E_BAD_MIGRATION:		return "Invalid migration properties";
1289 			case TPM_E_BAD_SCHEME:			return "Invalid signature or encryption scheme";
1290 			case TPM_E_BAD_DATASIZE:		return "Invalid data size";
1291 			case TPM_E_BAD_MODE:			return "Bad mode parameter";
1292 			case TPM_E_BAD_PRESENCE:		return "Bad physical presence value";
1293 			case TPM_E_BAD_VERSION:			return "Invalid version";
1294 			case TPM_E_NO_WRAP_TRANSPORT:		return "TPM does not allow for wrapped transport sessions";
1295 			case TPM_E_AUDITFAIL_UNSUCCESSFUL:	return "TPM audit construction failed and the underlying command was returning a failure code also";
1296 			case TPM_E_AUDITFAIL_SUCCESSFUL:	return "TPM audit construction failed and the underlying command was returning success";
1297 			case TPM_E_NOTRESETABLE:		return "Attempt to reset a PCR register that does not have the resettable attribute";
1298 			case TPM_E_NOTLOCAL:			return "Attempt to reset a PCR register that requires locality and locality modifier not part of command transport";
1299 			case TPM_E_BAD_TYPE:			return "Make identity blob not properly typed";
1300 			case TPM_E_INVALID_RESOURCE:		return "When saving context identified resource type does not match actual resource";
1301 			case TPM_E_NOTFIPS:			return "TPM is attempting to execute a command only available when in FIPS mode";
1302 			case TPM_E_INVALID_FAMILY:		return "Command is attempting to use an invalid family ID";
1303 			case TPM_E_NO_NV_PERMISSION:		return "Permission to manipulate the NV storage is not available";
1304 			case TPM_E_REQUIRES_SIGN:		return "Operation requires a signed command";
1305 			case TPM_E_KEY_NOTSUPPORTED:		return "Wrong operation to load an NV key";
1306 			case TPM_E_AUTH_CONFLICT:		return "NV_LoadKey blob requires both owner and blob authorization";
1307 			case TPM_E_AREA_LOCKED:			return "NV area is locked and not writable";
1308 			case TPM_E_BAD_LOCALITY:		return "Locality is incorrect for attempted operation";
1309 			case TPM_E_READ_ONLY:			return "NV area is read only and can't be written to";
1310 			case TPM_E_PER_NOWRITE:			return "There is no protection on write to NV area";
1311 			case TPM_E_FAMILYCOUNT:			return "Family count value does not match";
1312 			case TPM_E_WRITE_LOCKED:		return "NV area has already been written to";
1313 			case TPM_E_BAD_ATTRIBUTES:		return "NV area attributes conflict";
1314 			case TPM_E_INVALID_STRUCTURE:		return "Structure tag and version are invalid or inconsistent";
1315 			case TPM_E_KEY_OWNER_CONTROL:		return "Key is under control of TPM Owner and can only be evicted by TPM Owner";
1316 			case TPM_E_BAD_COUNTER:			return "Counter handle is incorrect";
1317 			case TPM_E_NOT_FULLWRITE:		return "Write is not a complete write of area";
1318 			case TPM_E_CONTEXT_GAP:			return "Gap between saved context counts is too large";
1319 			case TPM_E_MAXNVWRITES:			return "Maximum number of NV writes without an owner has been exceeded";
1320 			case TPM_E_NOOPERATOR:			return "No operator AuthData value is set";
1321 			case TPM_E_RESOURCEMISSING:		return "Resource pointed to by context is not loaded";
1322 			case TPM_E_DELEGATE_LOCK:		return "Delegate administration is locked";
1323 			case TPM_E_DELEGATE_FAMILY:		return "Attempt to manage a family other then delegated family";
1324 			case TPM_E_DELEGATE_ADMIN:		return "Delegation table management not enabled";
1325 			case TPM_E_TRANSPORT_NOTEXCLUSIVE:	return "A command was executed outside of an exclusive transport session";
1326 			case TPM_E_OWNER_CONTROL:		return "Attempt to context save an owner evict-controlled key";
1327 			case TPM_E_DAA_RESOURCES:		return "DAA command has no resources available to execute command";
1328 			case TPM_E_DAA_INPUT_DATA0:		return "Consistency check on DAA parameter inputData0 has failed";
1329 			case TPM_E_DAA_INPUT_DATA1:		return "Consistency check on DAA parameter inputData1 has failed";
1330 			case TPM_E_DAA_ISSUER_SETTINGS:		return "Consistency check on DAA_issuerSettings has failed";
1331 			case TPM_E_DAA_TPM_SETTINGS:		return "Consistency check on DAA_tpmSpecific has failed";
1332 			case TPM_E_DAA_STAGE:			return "Atomic process indicated by submitted DAA command is not expected process";
1333 			case TPM_E_DAA_ISSUER_VALIDITY:		return "Issuer's validity check has detected an inconsistency";
1334 			case TPM_E_DAA_WRONG_W:			return "Consistency check on w has failed";
1335 			case TPM_E_BAD_HANDLE:			return "Handle is incorrect";
1336 			case TPM_E_BAD_DELEGATE:		return "Delegation is not correct";
1337 			case TPM_E_BADCONTEXT:			return "Context blob is invalid";
1338 			case TPM_E_TOOMANYCONTEXTS:		return "Too many contexts held by TPM";
1339 			case TPM_E_MA_TICKET_SIGNATURE:		return "Migration authority signature validation failure";
1340 			case TPM_E_MA_DESTINATION:		return "Migration destination not authenticated";
1341 			case TPM_E_MA_SOURCE:			return "Migration source incorrect";
1342 			case TPM_E_MA_AUTHORITY:		return "Incorrect migration authority";
1343 			case TPM_E_PERMANENTEK:			return "Attempt to revoke EK but EK is not revocable";
1344 			case TPM_E_BAD_SIGNATURE:		return "Bad signature of CMK ticket";
1345 			case TPM_E_NOCONTEXTSPACE:		return "No room in context list for additional contexts";
1346 			case TPM_E_RETRY:			return "TPM busy: Retry command at a later time";
1347 			case TPM_E_NEEDS_SELFTEST:		return "SelfTestFull has not been run";
1348 			case TPM_E_DOING_SELFTEST:		return "TPM is currently executing a full selftest";
1349 			case TPM_E_DEFEND_LOCK_RUNNING:		return "TPM is defending against dictionary attacks and is in some time-out period";
1350 			case TPM_E_DISABLED_CMD:		return "The TPM target command has been disabled";
1351 			default:				return "Unknown error";
1352 		}
1353 	} else if (TSS_ERROR_LAYER(r) == TSS_LAYER_TDDL) {
1354 		switch (TSS_ERROR_CODE(r)) {
1355 			case TSS_E_FAIL:			return "General failure";
1356 			case TSS_E_BAD_PARAMETER:		return "Bad parameter";
1357 			case TSS_E_INTERNAL_ERROR:		return "Internal software error";
1358 			case TSS_E_NOTIMPL:			return "Not implemented";
1359 			case TSS_E_PS_KEY_NOTFOUND:		return "Key not found in persistent storage";
1360 			case TSS_E_KEY_ALREADY_REGISTERED:	return "UUID already registered";
1361 			case TSS_E_CANCELED:			return "The action was cancelled by request";
1362 			case TSS_E_TIMEOUT:			return "The operation has timed out";
1363 			case TSS_E_OUTOFMEMORY:			return "Out of memory";
1364 			case TSS_E_TPM_UNEXPECTED:		return "Unexpected TPM output";
1365 			case TSS_E_COMM_FAILURE:		return "Communication failure";
1366 			case TSS_E_TPM_UNSUPPORTED_FEATURE:	return "Unsupported feature";
1367 			case TDDL_E_COMPONENT_NOT_FOUND:	return "Connection to TPM device failed";
1368 			case TDDL_E_ALREADY_OPENED:		return "Device already opened";
1369 			case TDDL_E_BADTAG:			return "Invalid or unsupported capability";
1370 			case TDDL_E_INSUFFICIENT_BUFFER:	return "Receive buffer too small";
1371 			case TDDL_E_COMMAND_COMPLETED:		return "Command has already completed";
1372 			case TDDL_E_COMMAND_ABORTED:		return "TPM aborted processing of command";
1373 			case TDDL_E_ALREADY_CLOSED:		return "Device driver already closed";
1374 			case TDDL_E_IOERROR:			return "I/O error";
1375 			default:				return "Unknown";
1376 		}
1377 	} else if (TSS_ERROR_LAYER(r) == TSS_LAYER_TCS) {
1378 		switch (TSS_ERROR_CODE(r)) {
1379 			case TSS_E_FAIL:			return "General failure";
1380 			case TSS_E_BAD_PARAMETER:		return "Bad parameter";
1381 			case TSS_E_INTERNAL_ERROR:		return "Internal software error";
1382 			case TSS_E_NOTIMPL:			return "Not implemented";
1383 			case TSS_E_PS_KEY_NOTFOUND:		return "Key not found in persistent storage";
1384 			case TSS_E_KEY_ALREADY_REGISTERED:	return "UUID already registered";
1385 			case TSS_E_CANCELED:			return "The action was cancelled by request";
1386 			case TSS_E_TIMEOUT:			return "The operation has timed out";
1387 			case TSS_E_OUTOFMEMORY:			return "Out of memory";
1388 			case TSS_E_TPM_UNEXPECTED:		return "Unexpected TPM output";
1389 			case TSS_E_COMM_FAILURE:		return "Communication failure";
1390 			case TSS_E_TPM_UNSUPPORTED_FEATURE:	return "Unsupported feature";
1391 			case TCS_E_KEY_MISMATCH:		return "UUID does not match key handle";
1392 			case TCS_E_KM_LOADFAILED:		return "Key load failed: parent key requires authorization";
1393 			case TCS_E_KEY_CONTEXT_RELOAD:		return "Reload of key context failed";
1394 			case TCS_E_BAD_INDEX:			return "Bad memory index";
1395 			case TCS_E_INVALID_CONTEXTHANDLE:	return "Invalid context handle";
1396 			case TCS_E_INVALID_KEYHANDLE:		return "Invalid key handle";
1397 			case TCS_E_INVALID_AUTHHANDLE:		return "Invalid authorization session handle";
1398 			case TCS_E_INVALID_AUTHSESSION:		return "Authorization session has been closed by TPM";
1399 			case TCS_E_INVALID_KEY:			return "Invalid key";
1400 			default:				return "Unknown";
1401 		}
1402 	} else {
1403 		switch (TSS_ERROR_CODE(r)) {
1404 			case TSS_E_FAIL:			return "General failure";
1405 			case TSS_E_BAD_PARAMETER:		return "Bad parameter";
1406 			case TSS_E_INTERNAL_ERROR:		return "Internal software error";
1407 			case TSS_E_NOTIMPL:			return "Not implemented";
1408 			case TSS_E_PS_KEY_NOTFOUND:		return "Key not found in persistent storage";
1409 			case TSS_E_KEY_ALREADY_REGISTERED:	return "UUID already registered";
1410 			case TSS_E_CANCELED:			return "The action was cancelled by request";
1411 			case TSS_E_TIMEOUT:			return "The operation has timed out";
1412 			case TSS_E_OUTOFMEMORY:			return "Out of memory";
1413 			case TSS_E_TPM_UNEXPECTED:		return "Unexpected TPM output";
1414 			case TSS_E_COMM_FAILURE:		return "Communication failure";
1415 			case TSS_E_TPM_UNSUPPORTED_FEATURE:	return "Unsupported feature";
1416 			case TSS_E_INVALID_OBJECT_TYPE:		return "Object type not valid for this operation";
1417 			case TSS_E_INVALID_OBJECT_INITFLAG:	return "Wrong flag information for object creation";
1418 			case TSS_E_INVALID_HANDLE:		return "Invalid handle";
1419 			case TSS_E_NO_CONNECTION:		return "Core service connection doesn't exist";
1420 			case TSS_E_CONNECTION_FAILED:		return "Core service connection failed";
1421 			case TSS_E_CONNECTION_BROKEN:		return "Communication with core services failed";
1422 			case TSS_E_HASH_INVALID_ALG:		return "Invalid hash algorithm";
1423 			case TSS_E_HASH_INVALID_LENGTH:		return "Hash length is inconsistent with algorithm";
1424 			case TSS_E_HASH_NO_DATA:		return "Hash object has no internal hash value";
1425 			case TSS_E_SILENT_CONTEXT:		return "A silent context requires user input";
1426 			case TSS_E_INVALID_ATTRIB_FLAG:		return "Flag value for attrib-functions inconsistent";
1427 			case TSS_E_INVALID_ATTRIB_SUBFLAG:	return "Sub-flag value for attrib-functions inconsistent";
1428 			case TSS_E_INVALID_ATTRIB_DATA:		return "Data for attrib-functions invalid";
1429 			case TSS_E_NO_PCRS_SET:			return "No PCR registers are selected or set";
1430 			case TSS_E_KEY_NOT_LOADED:		return "The addressed key is not currently loaded";
1431 			case TSS_E_KEY_NOT_SET:			return "No key informatio is currently available";
1432 			case TSS_E_VALIDATION_FAILED:		return "Internal validation of data failed";
1433 			case TSS_E_TSP_AUTHREQUIRED:		return "Authorization is required";
1434 			case TSS_E_TSP_AUTH2REQUIRED:		return "Multiple authorizations are required";
1435 			case TSS_E_TSP_AUTHFAIL:		return "Authorization failed";
1436 			case TSS_E_TSP_AUTH2FAIL:		return "Multiple authorization failed";
1437 			case TSS_E_KEY_NO_MIGRATION_POLICY:	return "Addressed key has no migration policy";
1438 			case TSS_E_POLICY_NO_SECRET:		return "No secret information available for the address policy";
1439 			case TSS_E_INVALID_OBJ_ACCESS:		return "Accessed object is in an inconsistent state";
1440 			case TSS_E_INVALID_ENCSCHEME:		return "Invalid encryption scheme";
1441 			case TSS_E_INVALID_SIGSCHEME:		return "Invalid signature scheme";
1442 			case TSS_E_ENC_INVALID_LENGTH:		return "Invalid length for encrypted data object";
1443 			case TSS_E_ENC_NO_DATA:			return "Encrypted data object contains no data";
1444 			case TSS_E_ENC_INVALID_TYPE:		return "Invalid type for encrypted data object";
1445 			case TSS_E_INVALID_KEYUSAGE:		return "Invalid usage of key";
1446 			case TSS_E_VERIFICATION_FAILED:		return "Internal validation of data failed";
1447 			case TSS_E_HASH_NO_IDENTIFIER:		return "Hash algorithm identifier not set";
1448 			case TSS_E_NV_AREA_EXIST:		return "NVRAM area already exists";
1449 			case TSS_E_NV_AREA_NOT_EXIST:		return "NVRAM area does not exist";
1450 			default:				return "Unknown";
1451 		}
1452 	}
1453 }
1454 
1455 char *
1456 Trspi_Error_Layer(TSS_RESULT r)
1457 {
1458 	switch (TSS_ERROR_LAYER(r)) {
1459 		case TSS_LAYER_TPM:	return "tpm";
1460 		case TSS_LAYER_TDDL:	return "tddl";
1461 		case TSS_LAYER_TCS:	return "tcs";
1462 		case TSS_LAYER_TSP:	return "tsp";
1463 		default:		return "unknown";
1464 	}
1465 }
1466 
1467 TSS_RESULT
1468 Trspi_Error_Code(TSS_RESULT r)
1469 {
1470 	return TSS_ERROR_CODE(r);
1471 }
1472 
1473 static int
1474 hacky_strlen(char *codeset, BYTE *string)
1475 {
1476 	BYTE *ptr = string;
1477 	int len = 0;
1478 
1479 	if (strcmp("UTF-16", codeset) == 0) {
1480 		while (!(ptr[0] == '\0' && ptr[1] == '\0')) {
1481 			len += 2;
1482 			ptr += 2;
1483 		}
1484 	} else if (strcmp("UTF-32", codeset) == 0) {
1485 		while (!(ptr[0] == '\0' && ptr[1] == '\0' &&
1486 			 ptr[2] == '\0' && ptr[3] == '\0')) {
1487 			len += 4;
1488 			ptr += 4;
1489 		}
1490 	} else {
1491 		/* default to 8bit chars */
1492 		while (*ptr++ != '\0') {
1493 			len++;
1494 		}
1495 	}
1496 
1497 	return len;
1498 }
1499 
1500 static inline int
1501 char_width(char *codeset)
1502 {
1503 	if (strcmp("UTF-16", codeset) == 0) {
1504 		return 2;
1505 	} else if (strcmp("UTF-32", codeset) == 0) {
1506 		return 4;
1507 	}
1508 
1509 	return 1;
1510 }
1511 
1512 #define MAX_BUF_SIZE	4096
1513 
1514 BYTE *
1515 Trspi_Native_To_UNICODE(BYTE *string, unsigned *size)
1516 {
1517 	char *ret, *outbuf, tmpbuf[MAX_BUF_SIZE] = { 0, };
1518 	BSD_CONST char *ptr;
1519 	unsigned len = 0, tmplen;
1520 	iconv_t cd = 0;
1521 	size_t rc, outbytesleft, inbytesleft;
1522 
1523 	if (string == NULL)
1524 		goto alloc_string;
1525 
1526 	if ((cd = iconv_open("UTF-16LE", nl_langinfo(CODESET))) == (iconv_t)-1) {
1527 		LogDebug("iconv_open: %s", strerror(errno));
1528 		return NULL;
1529 	}
1530 
1531 	if ((tmplen = hacky_strlen(nl_langinfo(CODESET), string)) == 0) {
1532 		LogDebug("hacky_strlen returned 0");
1533 		goto alloc_string;
1534 	}
1535 
1536 	do {
1537 		len++;
1538 		outbytesleft = len;
1539 		inbytesleft = tmplen;
1540 		outbuf = tmpbuf;
1541 		ptr = (char *)string;
1542 		errno = 0;
1543 
1544 		rc = iconv(cd, (BSD_CONST char **)&ptr, &inbytesleft, &outbuf, &outbytesleft);
1545 	} while (rc == (size_t)-1 && errno == E2BIG);
1546 
1547 	if (len > MAX_BUF_SIZE) {
1548 		LogDebug("string too long.");
1549 		iconv_close(cd);
1550 		return NULL;
1551 	}
1552 
1553 alloc_string:
1554 	/* add terminating bytes of the correct width */
1555 	len += char_width("UTF-16");
1556 	if ((ret = calloc(1, len)) == NULL) {
1557 		LogDebug("malloc of %u bytes failed.", len);
1558 		iconv_close(cd);
1559 		return NULL;
1560 	}
1561 
1562 	memcpy(ret, &tmpbuf, len);
1563 	if (size)
1564 		*size = len;
1565 
1566 	if (cd)
1567 		iconv_close(cd);
1568 
1569 	return (BYTE *)ret;
1570 
1571 }
1572 
1573 BYTE *
1574 Trspi_UNICODE_To_Native(BYTE *string, unsigned *size)
1575 {
1576 	char *ret, *outbuf, tmpbuf[MAX_BUF_SIZE] = { 0, };
1577 	BSD_CONST char *ptr;
1578 	unsigned len = 0, tmplen;
1579 	iconv_t cd;
1580 	size_t rc, outbytesleft, inbytesleft;
1581 
1582 	if (string == NULL) {
1583 		if (size)
1584 			*size = 0;
1585 		return NULL;
1586 	}
1587 
1588 	if ((cd = iconv_open(nl_langinfo(CODESET), "UTF-16LE")) == (iconv_t)-1) {
1589 		LogDebug("iconv_open: %s", strerror(errno));
1590 		return NULL;
1591 	}
1592 
1593 	if ((tmplen = hacky_strlen("UTF-16", string)) == 0) {
1594 		LogDebug("hacky_strlen returned 0");
1595 		return 0;
1596 	}
1597 
1598 	do {
1599 		len++;
1600 		outbytesleft = len;
1601 		inbytesleft = tmplen;
1602 		outbuf = tmpbuf;
1603 		ptr = (char *)string;
1604 		errno = 0;
1605 
1606 		rc = iconv(cd, (BSD_CONST char **)&ptr, &inbytesleft, &outbuf, &outbytesleft);
1607 	} while (rc == (size_t)-1 && errno == E2BIG);
1608 
1609 	/* add terminating bytes of the correct width */
1610 	len += char_width(nl_langinfo(CODESET));
1611 	if (len > MAX_BUF_SIZE) {
1612 		LogDebug("string too long.");
1613 		iconv_close(cd);
1614 		return NULL;
1615 	}
1616 
1617 	if ((ret = calloc(1, len)) == NULL) {
1618 		LogDebug("malloc of %d bytes failed.", len);
1619 		iconv_close(cd);
1620 		return NULL;
1621 	}
1622 
1623 	memcpy(ret, &tmpbuf, len);
1624 	if (size)
1625 		*size = len;
1626 	iconv_close(cd);
1627 
1628 	return (BYTE *)ret;
1629 }
1630 
1631 /* Functions to support incremental hashing */
1632 TSS_RESULT
1633 Trspi_Hash_UINT16(Trspi_HashCtx *c, UINT16 i)
1634 {
1635 	BYTE bytes[sizeof(UINT16)];
1636 
1637 	UINT16ToArray(i, bytes);
1638 	return Trspi_HashUpdate(c, sizeof(UINT16), bytes);
1639 }
1640 
1641 TSS_RESULT
1642 Trspi_Hash_UINT32(Trspi_HashCtx *c, UINT32 i)
1643 {
1644 	BYTE bytes[sizeof(UINT32)];
1645 
1646 	UINT32ToArray(i, bytes);
1647 	return Trspi_HashUpdate(c, sizeof(UINT32), bytes);
1648 }
1649 
1650 TSS_RESULT
1651 Trspi_Hash_UINT64(Trspi_HashCtx *c, UINT64 i)
1652 {
1653 	BYTE bytes[sizeof(UINT64)];
1654 
1655 	UINT64ToArray(i, bytes);
1656 	return Trspi_HashUpdate(c, sizeof(UINT64), bytes);
1657 }
1658 
1659 TSS_RESULT
1660 Trspi_Hash_BYTE(Trspi_HashCtx *c, BYTE data)
1661 {
1662 	return Trspi_HashUpdate(c, sizeof(BYTE), &data);
1663 }
1664 
1665 TSS_RESULT
1666 Trspi_Hash_BOOL(Trspi_HashCtx *c, TSS_BOOL data)
1667 {
1668 	return Trspi_HashUpdate(c, (UINT32)sizeof(TSS_BOOL), (BYTE *)&data);
1669 }
1670 
1671 TSS_RESULT
1672 Trspi_Hash_VERSION(Trspi_HashCtx *c, TSS_VERSION *version)
1673 {
1674 	TSS_RESULT result;
1675 
1676 	result = Trspi_Hash_BYTE(c, version->bMajor);
1677 	result |= Trspi_Hash_BYTE(c, version->bMinor);
1678 	result |= Trspi_Hash_BYTE(c, version->bRevMajor);
1679 	result |= Trspi_Hash_BYTE(c, version->bRevMinor);
1680 
1681 	return result;
1682 }
1683 
1684 TSS_RESULT
1685 Trspi_Hash_DAA_PK(Trspi_HashCtx *c, TSS_DAA_PK *pk)
1686 {
1687 	UINT32 i;
1688 	TSS_RESULT result;
1689 
1690 	result = Trspi_Hash_VERSION(c, &pk->versionInfo);
1691 
1692 	result |= Trspi_Hash_UINT32(c, pk->modulusLength);
1693 	result |= Trspi_HashUpdate(c, pk->modulusLength, pk->modulus);
1694 
1695 	result |= Trspi_Hash_UINT32(c, pk->capitalSLength);
1696 	result |= Trspi_HashUpdate(c, pk->capitalSLength, pk->capitalS);
1697 
1698 	result |= Trspi_Hash_UINT32(c, pk->capitalZLength);
1699 	result |= Trspi_HashUpdate(c, pk->capitalZLength, pk->capitalZ);
1700 
1701 	result |= Trspi_Hash_UINT32(c, pk->capitalR0Length);
1702 	result |= Trspi_HashUpdate(c, pk->capitalR0Length, pk->capitalR0);
1703 
1704 	result |= Trspi_Hash_UINT32(c, pk->capitalR1Length);
1705 	result |= Trspi_HashUpdate(c, pk->capitalR1Length, pk->capitalR1);
1706 
1707 	result |= Trspi_Hash_UINT32(c, pk->gammaLength);
1708 	result |= Trspi_HashUpdate(c, pk->gammaLength, pk->gamma);
1709 
1710 	result |= Trspi_Hash_UINT32(c, pk->capitalGammaLength);
1711 	result |= Trspi_HashUpdate(c, pk->capitalGammaLength, pk->capitalGamma);
1712 
1713 	result |= Trspi_Hash_UINT32(c, pk->rhoLength);
1714 	result |= Trspi_HashUpdate(c, pk->rhoLength, pk->rho);
1715 
1716 	for (i = 0; i < pk->capitalYLength; i++)
1717 		result |= Trspi_HashUpdate(c, pk->capitalYLength2, pk->capitalY[i]);
1718 
1719 	result |= Trspi_Hash_UINT32(c, pk->capitalYPlatformLength);
1720 
1721 	result |= Trspi_Hash_UINT32(c, pk->issuerBaseNameLength);
1722 	result |= Trspi_HashUpdate(c, pk->issuerBaseNameLength, pk->issuerBaseName);
1723 
1724 	return result;
1725 }
1726 
1727 TSS_RESULT
1728 Trspi_Hash_RSA_KEY_PARMS(Trspi_HashCtx *c, TCPA_RSA_KEY_PARMS *parms)
1729 {
1730 	TSS_RESULT result;
1731 
1732 	result = Trspi_Hash_UINT32(c, parms->keyLength);
1733 	result |= Trspi_Hash_UINT32(c, parms->numPrimes);
1734 	result |= Trspi_Hash_UINT32(c, parms->exponentSize);
1735 
1736 	if (parms->exponentSize > 0)
1737 		result |= Trspi_HashUpdate(c, parms->exponentSize, parms->exponent);
1738 
1739 	return result;
1740 }
1741 
1742 TSS_RESULT
1743 Trspi_Hash_STORE_PUBKEY(Trspi_HashCtx *c, TCPA_STORE_PUBKEY *store)
1744 {
1745 	TSS_RESULT result;
1746 
1747 	result = Trspi_Hash_UINT32(c, store->keyLength);
1748 	result |= Trspi_HashUpdate(c, store->keyLength, store->key);
1749 
1750 	return result;
1751 }
1752 
1753 TSS_RESULT
1754 Trspi_Hash_KEY_PARMS(Trspi_HashCtx *c, TCPA_KEY_PARMS *keyInfo)
1755 {
1756 	TSS_RESULT result;
1757 
1758 	result = Trspi_Hash_UINT32(c, keyInfo->algorithmID);
1759 	result |= Trspi_Hash_UINT16(c, keyInfo->encScheme);
1760 	result |= Trspi_Hash_UINT16(c, keyInfo->sigScheme);
1761 	result |= Trspi_Hash_UINT32(c, keyInfo->parmSize);
1762 
1763 	if (keyInfo->parmSize > 0)
1764 		result |= Trspi_HashUpdate(c, keyInfo->parmSize, keyInfo->parms);
1765 
1766 	return result;
1767 }
1768 
1769 TSS_RESULT
1770 Trspi_Hash_PUBKEY(Trspi_HashCtx *c, TCPA_PUBKEY *pubKey)
1771 {
1772 	TSS_RESULT result;
1773 
1774 	result = Trspi_Hash_KEY_PARMS(c, &pubKey->algorithmParms);
1775 	result |= Trspi_Hash_STORE_PUBKEY(c, &pubKey->pubKey);
1776 
1777 	return result;
1778 }
1779 
1780 TSS_RESULT
1781 Trspi_Hash_STORED_DATA(Trspi_HashCtx *c, TCPA_STORED_DATA *data)
1782 {
1783 	TSS_RESULT result;
1784 
1785 	result = Trspi_Hash_VERSION(c, (TSS_VERSION *)&data->ver);
1786 	result |= Trspi_Hash_UINT32(c, data->sealInfoSize);
1787 	result |= Trspi_HashUpdate(c, data->sealInfoSize, data->sealInfo);
1788 	result |= Trspi_Hash_UINT32(c, data->encDataSize);
1789 	result |= Trspi_HashUpdate(c, data->encDataSize, data->encData);
1790 
1791 	return result;
1792 }
1793 
1794 TSS_RESULT
1795 Trspi_Hash_PCR_SELECTION(Trspi_HashCtx *c, TCPA_PCR_SELECTION *pcr)
1796 {
1797 	TSS_RESULT result;
1798 	UINT16 i;
1799 
1800 	result = Trspi_Hash_UINT16(c, pcr->sizeOfSelect);
1801 
1802 	for (i = 0; i < pcr->sizeOfSelect; i++)
1803 		result |= Trspi_Hash_BYTE(c, pcr->pcrSelect[i]);
1804 
1805 	return result;
1806 }
1807 
1808 TSS_RESULT
1809 Trspi_Hash_KEY_FLAGS(Trspi_HashCtx *c, TCPA_KEY_FLAGS *flags)
1810 {
1811 	return Trspi_Hash_UINT32(c, *flags);
1812 }
1813 
1814 TSS_RESULT
1815 Trspi_Hash_KEY12(Trspi_HashCtx *c, TPM_KEY12 *key)
1816 {
1817 	TSS_RESULT result;
1818 
1819 	result = Trspi_Hash_UINT16(c, key->tag);
1820 	result |= Trspi_Hash_UINT16(c, key->fill);
1821 	result |= Trspi_Hash_UINT16(c, key->keyUsage);
1822 	result |= Trspi_Hash_KEY_FLAGS(c, &key->keyFlags);
1823 	result |= Trspi_Hash_BYTE(c, key->authDataUsage);
1824 	result |= Trspi_Hash_KEY_PARMS(c, &key->algorithmParms);
1825 	result |= Trspi_Hash_UINT32(c, key->PCRInfoSize);
1826 	result |= Trspi_HashUpdate(c, key->PCRInfoSize, key->PCRInfo);
1827 	result |= Trspi_Hash_STORE_PUBKEY(c, &key->pubKey);
1828 	result |= Trspi_Hash_UINT32(c, key->encSize);
1829 	result |= Trspi_HashUpdate(c, key->encSize, key->encData);
1830 
1831 	return result;
1832 }
1833 
1834 TSS_RESULT
1835 Trspi_Hash_KEY(Trspi_HashCtx *c, TCPA_KEY *key)
1836 {
1837 	TSS_RESULT result;
1838 
1839 	result = Trspi_Hash_VERSION(c, (TSS_VERSION *)&key->ver);
1840 	result |= Trspi_Hash_UINT16(c, key->keyUsage);
1841 	result |= Trspi_Hash_KEY_FLAGS(c, &key->keyFlags);
1842 	result |= Trspi_Hash_BYTE(c, key->authDataUsage);
1843 	result |= Trspi_Hash_KEY_PARMS(c, &key->algorithmParms);
1844 	result |= Trspi_Hash_UINT32(c, key->PCRInfoSize);
1845 	result |= Trspi_HashUpdate(c, key->PCRInfoSize, key->PCRInfo);
1846 	result |= Trspi_Hash_STORE_PUBKEY(c, &key->pubKey);
1847 	result |= Trspi_Hash_UINT32(c, key->encSize);
1848 	result |= Trspi_HashUpdate(c, key->encSize, key->encData);
1849 
1850 	return result;
1851 }
1852 
1853 TSS_RESULT
1854 Trspi_Hash_UUID(Trspi_HashCtx *c, TSS_UUID uuid)
1855 {
1856 	TSS_RESULT result;
1857 
1858 	result = Trspi_Hash_UINT32(c, uuid.ulTimeLow);
1859 	result |= Trspi_Hash_UINT16(c, uuid.usTimeMid);
1860 	result |= Trspi_Hash_UINT16(c, uuid.usTimeHigh);
1861 	result |= Trspi_Hash_BYTE(c, uuid.bClockSeqHigh);
1862 	result |= Trspi_Hash_BYTE(c, uuid.bClockSeqLow);
1863 	result |= Trspi_HashUpdate(c, sizeof(uuid.rgbNode), uuid.rgbNode);
1864 
1865 	return result;
1866 }
1867 
1868 TSS_RESULT
1869 Trspi_Hash_PCR_EVENT(Trspi_HashCtx *c, TSS_PCR_EVENT *event)
1870 {
1871 	TSS_RESULT result;
1872 
1873 	result = Trspi_Hash_VERSION(c, &event->versionInfo);
1874 	result |= Trspi_Hash_UINT32(c, event->ulPcrIndex);
1875 	result |= Trspi_Hash_UINT32(c, event->eventType);
1876 
1877 	Trspi_Hash_UINT32(c, event->ulPcrValueLength);
1878 	if (event->ulPcrValueLength > 0)
1879 		result |= Trspi_HashUpdate(c, event->ulPcrValueLength, event->rgbPcrValue);
1880 
1881 	result |= Trspi_Hash_UINT32(c, event->ulEventLength);
1882 	if (event->ulEventLength > 0)
1883 		result |= Trspi_HashUpdate(c, event->ulEventLength, event->rgbEvent);
1884 
1885 
1886 	return result;
1887 }
1888 
1889 TSS_RESULT
1890 Trspi_Hash_PRIVKEY_DIGEST12(Trspi_HashCtx *c, TPM_KEY12 *key)
1891 {
1892 	TSS_RESULT result;
1893 
1894 	result = Trspi_Hash_UINT16(c, key->tag);
1895 	result |= Trspi_Hash_UINT16(c, key->fill);
1896 	result |= Trspi_Hash_UINT16(c, key->keyUsage);
1897 	result |= Trspi_Hash_KEY_FLAGS(c, &key->keyFlags);
1898 	result |= Trspi_Hash_BYTE(c, key->authDataUsage);
1899 	result |= Trspi_Hash_KEY_PARMS(c, &key->algorithmParms);
1900 
1901 	result |= Trspi_Hash_UINT32(c, key->PCRInfoSize);
1902 	/* exclude pcrInfo when PCRInfoSize is 0 as spec'd in TPM 1.1b spec p.71 */
1903 	if (key->PCRInfoSize != 0)
1904 		result |= Trspi_HashUpdate(c, key->PCRInfoSize, key->PCRInfo);
1905 
1906 	Trspi_Hash_STORE_PUBKEY(c, &key->pubKey);
1907 	/* exclude encSize, encData as spec'd in TPM 1.1b spec p.71 */
1908 
1909 	return result;
1910 }
1911 
1912 TSS_RESULT
1913 Trspi_Hash_PRIVKEY_DIGEST(Trspi_HashCtx *c, TCPA_KEY *key)
1914 {
1915 	TSS_RESULT result;
1916 
1917 	result = Trspi_Hash_VERSION(c, (TSS_VERSION *)&key->ver);
1918 	result |= Trspi_Hash_UINT16(c, key->keyUsage);
1919 	result |= Trspi_Hash_KEY_FLAGS(c, &key->keyFlags);
1920 	result |= Trspi_Hash_BYTE(c, key->authDataUsage);
1921 	result |= Trspi_Hash_KEY_PARMS(c, &key->algorithmParms);
1922 
1923 	result |= Trspi_Hash_UINT32(c, key->PCRInfoSize);
1924 	/* exclude pcrInfo when PCRInfoSize is 0 as spec'd in TPM 1.1b spec p.71 */
1925 	if (key->PCRInfoSize != 0)
1926 		result |= Trspi_HashUpdate(c, key->PCRInfoSize, key->PCRInfo);
1927 
1928 	Trspi_Hash_STORE_PUBKEY(c, &key->pubKey);
1929 	/* exclude encSize, encData as spec'd in TPM 1.1b spec p.71 */
1930 
1931 	return result;
1932 }
1933 
1934 TSS_RESULT
1935 Trspi_Hash_SYMMETRIC_KEY(Trspi_HashCtx *c, TCPA_SYMMETRIC_KEY *key)
1936 {
1937 	TSS_RESULT result;
1938 
1939 	result = Trspi_Hash_UINT32(c, key->algId);
1940 	result |= Trspi_Hash_UINT16(c, key->encScheme);
1941 	result |= Trspi_Hash_UINT16(c, key->size);
1942 
1943 	if (key->size > 0)
1944 		result |= Trspi_HashUpdate(c, key->size, key->data);
1945 
1946 	return result;
1947 }
1948 
1949 TSS_RESULT
1950 Trspi_Hash_IDENTITY_REQ(Trspi_HashCtx *c, TCPA_IDENTITY_REQ *req)
1951 {
1952 	TSS_RESULT result;
1953 
1954 	result = Trspi_Hash_UINT32(c, req->asymSize);
1955 	result |= Trspi_Hash_UINT32(c, req->symSize);
1956 	result |= Trspi_Hash_KEY_PARMS(c, &req->asymAlgorithm);
1957 	result |= Trspi_Hash_KEY_PARMS(c, &req->symAlgorithm);
1958 	result |= Trspi_HashUpdate(c, req->asymSize, req->asymBlob);
1959 	result |= Trspi_HashUpdate(c, req->symSize, req->symBlob);
1960 
1961 	return result;
1962 }
1963 
1964 TSS_RESULT
1965 Trspi_Hash_CHANGEAUTH_VALIDATE(Trspi_HashCtx *c, TPM_CHANGEAUTH_VALIDATE *caValidate)
1966 {
1967 	TSS_RESULT result;
1968 
1969 	result = Trspi_HashUpdate(c, TCPA_SHA1_160_HASH_LEN, caValidate->newAuthSecret.authdata);
1970 	result |= Trspi_HashUpdate(c, TCPA_SHA1_160_HASH_LEN, caValidate->n1.nonce);
1971 
1972 	return result;
1973 }
1974 
1975 TSS_RESULT
1976 Trspi_Hash_SYM_CA_ATTESTATION(Trspi_HashCtx *c, TCPA_SYM_CA_ATTESTATION *sym)
1977 {
1978 	TSS_RESULT result;
1979 
1980 	result = Trspi_Hash_UINT32(c, sym->credSize);
1981 	result |= Trspi_Hash_KEY_PARMS(c, &sym->algorithm);
1982 	result |= Trspi_HashUpdate(c, sym->credSize, sym->credential);
1983 
1984 	return result;
1985 }
1986 
1987 TSS_RESULT
1988 Trspi_Hash_ASYM_CA_CONTENTS(Trspi_HashCtx *c, TCPA_ASYM_CA_CONTENTS *asym)
1989 {
1990 	TSS_RESULT result;
1991 
1992 	result = Trspi_Hash_SYMMETRIC_KEY(c, &asym->sessionKey);
1993 	result |= Trspi_HashUpdate(c, TCPA_SHA1_160_HASH_LEN, (BYTE *)&asym->idDigest);
1994 
1995 	return result;
1996 }
1997 
1998 TSS_RESULT
1999 Trspi_Hash_BOUND_DATA(Trspi_HashCtx *c, TCPA_BOUND_DATA *bd, UINT32 payloadLength)
2000 {
2001 	TSS_RESULT result;
2002 
2003 	result = Trspi_Hash_VERSION(c, (TSS_VERSION *)&bd->ver);
2004 	result |= Trspi_Hash_BYTE(c, bd->payload);
2005 	result |= Trspi_HashUpdate(c, payloadLength, bd->payloadData);
2006 
2007 	return result;
2008 }
2009 
2010 TSS_RESULT
2011 Trspi_Hash_TRANSPORT_AUTH(Trspi_HashCtx *c, TPM_TRANSPORT_AUTH *a)
2012 {
2013 	TSS_RESULT result;
2014 
2015 	result = Trspi_Hash_UINT16(c, a->tag);
2016 	result |= Trspi_HashUpdate(c, TPM_SHA1_160_HASH_LEN, a->authData.authdata);
2017 
2018 	return result;
2019 }
2020 
2021 TSS_RESULT
2022 Trspi_Hash_TRANSPORT_LOG_IN(Trspi_HashCtx *c, TPM_TRANSPORT_LOG_IN *l)
2023 {
2024 	TSS_RESULT result;
2025 
2026 	result = Trspi_Hash_UINT16(c, l->tag);
2027 	result |= Trspi_Hash_DIGEST(c, l->parameters.digest);
2028 	result |= Trspi_Hash_DIGEST(c, l->pubKeyHash.digest);
2029 
2030 	return result;
2031 }
2032 
2033 TSS_RESULT
2034 Trspi_Hash_TRANSPORT_LOG_OUT(Trspi_HashCtx *c, TPM_TRANSPORT_LOG_OUT *l)
2035 {
2036 	TSS_RESULT result;
2037 
2038 	result = Trspi_Hash_UINT16(c, l->tag);
2039 	result |= Trspi_Hash_CURRENT_TICKS(c, &l->currentTicks);
2040 	result |= Trspi_Hash_DIGEST(c, l->parameters.digest);
2041 	result |= Trspi_Hash_UINT32(c, l->locality);
2042 
2043 	return result;
2044 }
2045 
2046 TSS_RESULT
2047 Trspi_Hash_CURRENT_TICKS(Trspi_HashCtx *c, TPM_CURRENT_TICKS *t)
2048 {
2049 	TSS_RESULT result;
2050 
2051 	result = Trspi_Hash_UINT16(c, t->tag);
2052 	result |= Trspi_Hash_UINT64(c, t->currentTicks);
2053 	result |= Trspi_Hash_UINT16(c, t->tickRate);
2054 	result |= Trspi_Hash_NONCE(c, t->tickNonce.nonce);
2055 
2056 	return result;
2057 }
2058 
2059 TSS_RESULT
2060 Trspi_Hash_SIGN_INFO(Trspi_HashCtx *c, TPM_SIGN_INFO *s)
2061 {
2062 	TSS_RESULT result;
2063 
2064 	result = Trspi_Hash_UINT16(c, s->tag);
2065 	result |= Trspi_HashUpdate(c, 4, s->fixed);
2066 	result |= Trspi_Hash_NONCE(c, s->replay.nonce);
2067 	result |= Trspi_Hash_UINT32(c, s->dataLen);
2068 	result |= Trspi_HashUpdate(c, s->dataLen, s->data);
2069 
2070 	return result;
2071 }
2072 
2073 void
2074 Trspi_UnloadBlob_COUNTER_VALUE(UINT64 *offset, BYTE *blob, TPM_COUNTER_VALUE *ctr)
2075 {
2076 	if (!ctr) {
2077 		Trspi_UnloadBlob_UINT16(offset, NULL, blob);
2078 		/* '4' is hard-coded in the spec */
2079 		Trspi_UnloadBlob(offset, 4, blob, NULL);
2080 		Trspi_UnloadBlob_UINT32(offset, NULL, blob);
2081 
2082 		return;
2083 	}
2084 
2085 	Trspi_UnloadBlob_UINT16(offset, &ctr->tag, blob);
2086 	/* '4' is hard-coded in the spec */
2087 	Trspi_UnloadBlob(offset, 4, blob, (BYTE *)&ctr->label);
2088 	Trspi_UnloadBlob_UINT32(offset, &ctr->counter, blob);
2089 }
2090 
2091 void
2092 Trspi_LoadBlob_COUNTER_VALUE(UINT64 *offset, BYTE *blob, TPM_COUNTER_VALUE *ctr)
2093 {
2094 	Trspi_LoadBlob_UINT16(offset, ctr->tag, blob);
2095 	Trspi_LoadBlob(offset, 4, blob, (BYTE *)&ctr->label);
2096 	Trspi_LoadBlob_UINT32(offset, ctr->counter, blob);
2097 }
2098 
2099 void
2100 Trspi_UnloadBlob_CURRENT_TICKS(UINT64 *offset, BYTE *blob, TPM_CURRENT_TICKS *ticks)
2101 {
2102 	if (!ticks) {
2103 		Trspi_UnloadBlob_UINT16(offset, NULL, blob);
2104 		Trspi_UnloadBlob_UINT64(offset, NULL, blob);
2105 		Trspi_UnloadBlob_UINT16(offset, NULL, blob);
2106 		Trspi_UnloadBlob(offset, sizeof(TPM_NONCE), blob, NULL);
2107 
2108 		return;
2109 	}
2110 
2111 	Trspi_UnloadBlob_UINT16(offset, &ticks->tag, blob);
2112 	Trspi_UnloadBlob_UINT64(offset, &ticks->currentTicks, blob);
2113 	Trspi_UnloadBlob_UINT16(offset, &ticks->tickRate, blob);
2114 	Trspi_UnloadBlob(offset, sizeof(TPM_NONCE), blob, (BYTE *)&ticks->tickNonce);
2115 }
2116 
2117 void
2118 Trspi_UnloadBlob_TRANSPORT_PUBLIC(UINT64 *offset, BYTE *blob, TPM_TRANSPORT_PUBLIC *t)
2119 {
2120 	Trspi_UnloadBlob_UINT16(offset, &t->tag, blob);
2121 	Trspi_UnloadBlob_UINT32(offset, &t->transAttributes, blob);
2122 	Trspi_UnloadBlob_UINT32(offset, &t->algId, blob);
2123 	Trspi_UnloadBlob_UINT16(offset, &t->encScheme, blob);
2124 }
2125 
2126 void
2127 Trspi_LoadBlob_TRANSPORT_PUBLIC(UINT64 *offset, BYTE *blob, TPM_TRANSPORT_PUBLIC *t)
2128 {
2129 	Trspi_LoadBlob_UINT16(offset, t->tag, blob);
2130 	Trspi_LoadBlob_UINT32(offset, t->transAttributes, blob);
2131 	Trspi_LoadBlob_UINT32(offset, t->algId, blob);
2132 	Trspi_LoadBlob_UINT16(offset, t->encScheme, blob);
2133 }
2134 
2135 void
2136 Trspi_LoadBlob_TRANSPORT_AUTH(UINT64 *offset, BYTE *blob, TPM_TRANSPORT_AUTH *t)
2137 {
2138 	Trspi_LoadBlob_UINT16(offset, t->tag, blob);
2139 	Trspi_LoadBlob(offset, TPM_SHA1_160_HASH_LEN, blob, t->authData.authdata);
2140 }
2141 
2142 void
2143 Trspi_LoadBlob_SIGN_INFO(UINT64 *offset, BYTE *blob, TPM_SIGN_INFO *s)
2144 {
2145 	Trspi_LoadBlob_UINT16(offset, s->tag, blob);
2146 	Trspi_LoadBlob(offset, 4, blob, s->fixed);
2147 	Trspi_LoadBlob(offset, TPM_SHA1_160_HASH_LEN, blob, s->replay.nonce);
2148 	Trspi_LoadBlob_UINT32(offset, s->dataLen, blob);
2149 	Trspi_LoadBlob(offset, s->dataLen, blob, s->data);
2150 }
2151 
2152 TSS_RESULT
2153 Trspi_UnloadBlob_CERTIFY_INFO(UINT64 *offset, BYTE *blob, TPM_CERTIFY_INFO *c)
2154 {
2155 	TSS_RESULT result;
2156 
2157 	if (!c) {
2158 		UINT32 pcrInfoSize;
2159 
2160 		Trspi_UnloadBlob_VERSION(offset, blob, NULL);
2161 		Trspi_UnloadBlob_UINT16(offset, NULL, blob);
2162 		Trspi_UnloadBlob_UINT32(offset, NULL, blob);
2163 		Trspi_UnloadBlob_BYTE(offset, NULL, blob);
2164 		Trspi_UnloadBlob_KEY_PARMS(offset, blob, NULL);
2165 		Trspi_UnloadBlob_DIGEST(offset, blob, NULL);
2166 		Trspi_UnloadBlob_NONCE(offset, blob, NULL);
2167 		Trspi_UnloadBlob_BOOL(offset, NULL, blob);
2168 		Trspi_UnloadBlob_UINT32(offset, &pcrInfoSize, blob);
2169 
2170 		(*offset) += pcrInfoSize;
2171 
2172 		return TSS_SUCCESS;
2173 	}
2174 
2175 	Trspi_UnloadBlob_VERSION(offset, blob, &c->version);
2176 	Trspi_UnloadBlob_UINT16(offset, &c->keyUsage, blob);
2177 	Trspi_UnloadBlob_UINT32(offset, &c->keyFlags, blob);
2178 	Trspi_UnloadBlob_BYTE(offset, &c->authDataUsage, blob);
2179 	if ((result = Trspi_UnloadBlob_KEY_PARMS(offset, blob, &c->algorithmParms)))
2180 		return result;
2181 	Trspi_UnloadBlob_DIGEST(offset, blob, &c->pubkeyDigest);
2182 	Trspi_UnloadBlob_NONCE(offset, blob, &c->data);
2183 	Trspi_UnloadBlob_BOOL(offset, (TSS_BOOL *)&c->parentPCRStatus, blob);
2184 	Trspi_UnloadBlob_UINT32(offset, &c->PCRInfoSize, blob);
2185         if (c->PCRInfoSize != 0) {
2186                 c->PCRInfo = malloc(sizeof(TPM_PCR_INFO));
2187                 if (c->PCRInfo == NULL) {
2188                         LogError("malloc of %lu bytes failed.", sizeof(TPM_PCR_INFO));
2189                         return TSPERR(TSS_E_OUTOFMEMORY);
2190                 }
2191         } else {
2192                 c->PCRInfo = NULL;
2193         }
2194         Trspi_UnloadBlob_PCR_INFO(offset, blob, (TPM_PCR_INFO *)c->PCRInfo);
2195 
2196 	return TSS_SUCCESS;
2197 }
2198 
2199 void
2200 Trspi_UnloadBlob_TPM_FAMILY_LABEL(UINT64 *offset, BYTE *blob, TPM_FAMILY_LABEL *label)
2201 {
2202 	if (!label) {
2203 		Trspi_UnloadBlob_BYTE(offset, NULL, blob);
2204 
2205 		return;
2206 	}
2207 
2208 	Trspi_UnloadBlob_BYTE(offset, &label->label, blob);
2209 }
2210 
2211 void
2212 Trspi_LoadBlob_TPM_FAMILY_LABEL(UINT64 *offset, BYTE *blob, TPM_FAMILY_LABEL *label)
2213 {
2214 	Trspi_LoadBlob_BYTE(offset, label->label, blob);
2215 }
2216 
2217 void
2218 Trspi_UnloadBlob_TPM_FAMILY_TABLE_ENTRY(UINT64 *offset, BYTE *blob, TPM_FAMILY_TABLE_ENTRY *entry)
2219 {
2220 	if (!entry) {
2221 		Trspi_UnloadBlob_UINT16(offset, NULL, blob);
2222 		Trspi_UnloadBlob_TPM_FAMILY_LABEL(offset, blob, NULL);
2223 		Trspi_UnloadBlob_UINT32(offset, NULL, blob);
2224 		Trspi_UnloadBlob_UINT32(offset, NULL, blob);
2225 		Trspi_UnloadBlob_UINT32(offset, NULL, blob);
2226 
2227 		return;
2228 	}
2229 
2230 	Trspi_UnloadBlob_UINT16(offset, &entry->tag, blob);
2231 	Trspi_UnloadBlob_TPM_FAMILY_LABEL(offset, blob, &entry->label);
2232 	Trspi_UnloadBlob_UINT32(offset, &entry->familyID, blob);
2233 	Trspi_UnloadBlob_UINT32(offset, &entry->verificationCount, blob);
2234 	Trspi_UnloadBlob_UINT32(offset, &entry->flags, blob);
2235 }
2236 
2237 void
2238 Trspi_LoadBlob_TPM_FAMILY_TABLE_ENTRY(UINT64 *offset, BYTE *blob, TPM_FAMILY_TABLE_ENTRY *entry)
2239 {
2240 	Trspi_LoadBlob_UINT16(offset, entry->tag, blob);
2241 	Trspi_LoadBlob_TPM_FAMILY_LABEL(offset, blob, &entry->label);
2242 	Trspi_LoadBlob_UINT32(offset, entry->familyID, blob);
2243 	Trspi_LoadBlob_UINT32(offset, entry->verificationCount, blob);
2244 	Trspi_LoadBlob_UINT32(offset, entry->flags, blob);
2245 }
2246 
2247 void
2248 Trspi_UnloadBlob_TPM_DELEGATE_LABEL(UINT64 *offset, BYTE *blob, TPM_DELEGATE_LABEL *label)
2249 {
2250 	if (!label) {
2251 		Trspi_UnloadBlob_BYTE(offset, NULL, blob);
2252 
2253 		return;
2254 	}
2255 
2256 	Trspi_UnloadBlob_BYTE(offset, &label->label, blob);
2257 }
2258 
2259 void
2260 Trspi_LoadBlob_TPM_DELEGATE_LABEL(UINT64 *offset, BYTE *blob, TPM_DELEGATE_LABEL *label)
2261 {
2262 	Trspi_LoadBlob_BYTE(offset, label->label, blob);
2263 }
2264 
2265 void
2266 Trspi_UnloadBlob_TPM_DELEGATIONS(UINT64 *offset, BYTE *blob, TPM_DELEGATIONS *delegations)
2267 {
2268 	if (!delegations) {
2269 		Trspi_UnloadBlob_UINT16(offset, NULL, blob);
2270 		Trspi_UnloadBlob_UINT32(offset, NULL, blob);
2271 		Trspi_UnloadBlob_UINT32(offset, NULL, blob);
2272 		Trspi_UnloadBlob_UINT32(offset, NULL, blob);
2273 
2274 		return;
2275 	}
2276 
2277 	Trspi_UnloadBlob_UINT16(offset, &delegations->tag, blob);
2278 	Trspi_UnloadBlob_UINT32(offset, &delegations->delegateType, blob);
2279 	Trspi_UnloadBlob_UINT32(offset, &delegations->per1, blob);
2280 	Trspi_UnloadBlob_UINT32(offset, &delegations->per2, blob);
2281 }
2282 
2283 void
2284 Trspi_LoadBlob_TPM_DELEGATIONS(UINT64 *offset, BYTE *blob, TPM_DELEGATIONS *delegations)
2285 {
2286 	Trspi_LoadBlob_UINT16(offset, delegations->tag, blob);
2287 	Trspi_LoadBlob_UINT32(offset, delegations->delegateType, blob);
2288 	Trspi_LoadBlob_UINT32(offset, delegations->per1, blob);
2289 	Trspi_LoadBlob_UINT32(offset, delegations->per2, blob);
2290 }
2291 
2292 TSS_RESULT
2293 Trspi_UnloadBlob_TPM_DELEGATE_PUBLIC(UINT64 *offset, BYTE *blob, TPM_DELEGATE_PUBLIC *pub)
2294 {
2295 	TSS_RESULT result;
2296 
2297 	if (!pub) {
2298 		Trspi_UnloadBlob_UINT16(offset, NULL, blob);
2299 		Trspi_UnloadBlob_TPM_DELEGATE_LABEL(offset, blob, NULL);
2300 		(void)Trspi_UnloadBlob_PCR_INFO_SHORT(offset, blob, NULL);
2301 		Trspi_UnloadBlob_TPM_DELEGATIONS(offset, blob, NULL);
2302 		Trspi_UnloadBlob_UINT32(offset, NULL, blob);
2303 		Trspi_UnloadBlob_UINT32(offset, NULL, blob);
2304 
2305 		return TSS_SUCCESS;
2306 	}
2307 
2308 	Trspi_UnloadBlob_UINT16(offset, &pub->tag, blob);
2309 	Trspi_UnloadBlob_TPM_DELEGATE_LABEL(offset, blob, &pub->label);
2310 	if ((result = Trspi_UnloadBlob_PCR_INFO_SHORT(offset, blob, &pub->pcrInfo)))
2311 		return result;
2312 	Trspi_UnloadBlob_TPM_DELEGATIONS(offset, blob, &pub->permissions);
2313 	Trspi_UnloadBlob_UINT32(offset, &pub->familyID, blob);
2314 	Trspi_UnloadBlob_UINT32(offset, &pub->verificationCount, blob);
2315 
2316 	return TSS_SUCCESS;
2317 }
2318 
2319 void
2320 Trspi_LoadBlob_TPM_DELEGATE_PUBLIC(UINT64 *offset, BYTE *blob, TPM_DELEGATE_PUBLIC *pub)
2321 {
2322 	Trspi_LoadBlob_UINT16(offset, pub->tag, blob);
2323 	Trspi_LoadBlob_TPM_DELEGATE_LABEL(offset, blob, &pub->label);
2324 	Trspi_LoadBlob_PCR_INFO_SHORT(offset, blob, &pub->pcrInfo);
2325 	Trspi_LoadBlob_TPM_DELEGATIONS(offset, blob, &pub->permissions);
2326 	Trspi_LoadBlob_UINT32(offset, pub->familyID, blob);
2327 	Trspi_LoadBlob_UINT32(offset, pub->verificationCount, blob);
2328 }
2329 
2330 TSS_RESULT
2331 Trspi_UnloadBlob_TPM_DELEGATE_OWNER_BLOB(UINT64 *offset, BYTE *blob, TPM_DELEGATE_OWNER_BLOB *owner)
2332 {
2333 	TSS_RESULT result;
2334 
2335 	if (!owner) {
2336 		UINT32 additionalSize, sensitiveSize;
2337 
2338 		Trspi_UnloadBlob_UINT16(offset, NULL, blob);
2339 		(void)Trspi_UnloadBlob_TPM_DELEGATE_PUBLIC(offset, blob, NULL);
2340 		Trspi_UnloadBlob_DIGEST(offset, blob, NULL);
2341 		Trspi_UnloadBlob_UINT32(offset, &additionalSize, blob);
2342 		(void)Trspi_UnloadBlob(offset, additionalSize, blob, NULL);
2343 		Trspi_UnloadBlob_UINT32(offset, &sensitiveSize, blob);
2344 		(void)Trspi_UnloadBlob(offset, sensitiveSize, blob, NULL);
2345 
2346 		return TSS_SUCCESS;
2347 	}
2348 
2349 	Trspi_UnloadBlob_UINT16(offset, &owner->tag, blob);
2350 	if ((result = Trspi_UnloadBlob_TPM_DELEGATE_PUBLIC(offset, blob, &owner->pub)))
2351 		return result;
2352 	Trspi_UnloadBlob_DIGEST(offset, blob, &owner->integrityDigest);
2353 	Trspi_UnloadBlob_UINT32(offset, &owner->additionalSize, blob);
2354 	if (owner->additionalSize > 0) {
2355 		owner->additionalArea = malloc(owner->additionalSize);
2356 		if (owner->additionalArea == NULL) {
2357 			LogError("malloc of %u bytes failed.", owner->additionalSize);
2358 			free(owner->pub.pcrInfo.pcrSelection.pcrSelect);
2359 			return TSPERR(TSS_E_OUTOFMEMORY);
2360 		}
2361 		Trspi_UnloadBlob(offset, owner->additionalSize, blob, owner->additionalArea);
2362 	}
2363 	Trspi_UnloadBlob_UINT32(offset, &owner->sensitiveSize, blob);
2364 	if (owner->sensitiveSize > 0) {
2365 		owner->sensitiveArea = malloc(owner->sensitiveSize);
2366 		if (owner->sensitiveArea == NULL) {
2367 			LogError("malloc of %u bytes failed.", owner->sensitiveSize);
2368 			free(owner->pub.pcrInfo.pcrSelection.pcrSelect);
2369 			free(owner->additionalArea);
2370 			return TSPERR(TSS_E_OUTOFMEMORY);
2371 		}
2372 		Trspi_UnloadBlob(offset, owner->sensitiveSize, blob, owner->sensitiveArea);
2373 	}
2374 
2375 	return TSS_SUCCESS;
2376 }
2377 
2378 void
2379 Trspi_LoadBlob_TPM_DELEGATE_OWNER_BLOB(UINT64 *offset, BYTE *blob, TPM_DELEGATE_OWNER_BLOB *owner)
2380 {
2381 	Trspi_LoadBlob_UINT16(offset, owner->tag, blob);
2382 	Trspi_LoadBlob_TPM_DELEGATE_PUBLIC(offset, blob, &owner->pub);
2383 	Trspi_LoadBlob_DIGEST(offset, blob, &owner->integrityDigest);
2384 	Trspi_LoadBlob_UINT32(offset, owner->additionalSize, blob);
2385 	Trspi_LoadBlob(offset, owner->additionalSize, blob, owner->additionalArea);
2386 	Trspi_LoadBlob_UINT32(offset, owner->sensitiveSize, blob);
2387 	Trspi_LoadBlob(offset, owner->sensitiveSize, blob, owner->sensitiveArea);
2388 }
2389 
2390 TSS_RESULT
2391 Trspi_UnloadBlob_TPM_DELEGATE_KEY_BLOB(UINT64 *offset, BYTE *blob, TPM_DELEGATE_KEY_BLOB *key)
2392 {
2393 	TSS_RESULT result;
2394 
2395 	if (!key) {
2396 		UINT32 additionalSize, sensitiveSize;
2397 
2398 		Trspi_UnloadBlob_UINT16(offset, NULL, blob);
2399 		(void)Trspi_UnloadBlob_TPM_DELEGATE_PUBLIC(offset, blob, NULL);
2400 		Trspi_UnloadBlob_DIGEST(offset, blob, NULL);
2401 		Trspi_UnloadBlob_DIGEST(offset, blob, NULL);
2402 		Trspi_UnloadBlob_UINT32(offset, &additionalSize, blob);
2403 		(void)Trspi_UnloadBlob(offset, additionalSize, blob, NULL);
2404 		Trspi_UnloadBlob_UINT32(offset, &sensitiveSize, blob);
2405 		(void)Trspi_UnloadBlob(offset, sensitiveSize, blob, NULL);
2406 
2407 		return TSS_SUCCESS;
2408 	}
2409 
2410 	Trspi_UnloadBlob_UINT16(offset, &key->tag, blob);
2411 	if ((result = Trspi_UnloadBlob_TPM_DELEGATE_PUBLIC(offset, blob, &key->pub)))
2412 		return result;
2413 	Trspi_UnloadBlob_DIGEST(offset, blob, &key->integrityDigest);
2414 	Trspi_UnloadBlob_DIGEST(offset, blob, &key->pubKeyDigest);
2415 	Trspi_UnloadBlob_UINT32(offset, &key->additionalSize, blob);
2416 	if (key->additionalSize > 0) {
2417 		key->additionalArea = malloc(key->additionalSize);
2418 		if (key->additionalArea == NULL) {
2419 			LogError("malloc of %u bytes failed.", key->additionalSize);
2420 			free(key->pub.pcrInfo.pcrSelection.pcrSelect);
2421 			return TSPERR(TSS_E_OUTOFMEMORY);
2422 		}
2423 		Trspi_UnloadBlob(offset, key->additionalSize, blob, key->additionalArea);
2424 	}
2425 	Trspi_UnloadBlob_UINT32(offset, &key->sensitiveSize, blob);
2426 	if (key->sensitiveSize > 0) {
2427 		key->sensitiveArea = malloc(key->sensitiveSize);
2428 		if (key->sensitiveArea == NULL) {
2429 			LogError("malloc of %u bytes failed.", key->sensitiveSize);
2430 			free(key->pub.pcrInfo.pcrSelection.pcrSelect);
2431 			free(key->additionalArea);
2432 			return TSPERR(TSS_E_OUTOFMEMORY);
2433 		}
2434 		Trspi_UnloadBlob(offset, key->sensitiveSize, blob, key->sensitiveArea);
2435 	}
2436 
2437 	return TSS_SUCCESS;
2438 }
2439 
2440 void
2441 Trspi_LoadBlob_TPM_DELEGATE_KEY_BLOB(UINT64 *offset, BYTE *blob, TPM_DELEGATE_KEY_BLOB *key)
2442 {
2443 	Trspi_LoadBlob_UINT16(offset, key->tag, blob);
2444 	Trspi_LoadBlob_TPM_DELEGATE_PUBLIC(offset, blob, &key->pub);
2445 	Trspi_LoadBlob_DIGEST(offset, blob, &key->integrityDigest);
2446 	Trspi_LoadBlob_DIGEST(offset, blob, &key->pubKeyDigest);
2447 	Trspi_LoadBlob_UINT32(offset, key->additionalSize, blob);
2448 	Trspi_LoadBlob(offset, key->additionalSize, blob, key->additionalArea);
2449 	Trspi_LoadBlob_UINT32(offset, key->sensitiveSize, blob);
2450 	Trspi_LoadBlob(offset, key->sensitiveSize, blob, key->sensitiveArea);
2451 }
2452 
2453 void
2454 Trspi_UnloadBlob_TSS_FAMILY_TABLE_ENTRY(UINT64 *offset, BYTE *blob, TSS_FAMILY_TABLE_ENTRY *entry)
2455 {
2456 	if (!entry) {
2457 		Trspi_UnloadBlob_UINT32(offset, NULL, blob);
2458 		Trspi_UnloadBlob_BYTE(offset, NULL, blob);
2459 		Trspi_UnloadBlob_UINT32(offset, NULL, blob);
2460 		Trspi_UnloadBlob_BOOL(offset, NULL, blob);
2461 		Trspi_UnloadBlob_BOOL(offset, NULL, blob);
2462 
2463 		return;
2464 	}
2465 
2466 	Trspi_UnloadBlob_UINT32(offset, &entry->familyID, blob);
2467 	Trspi_UnloadBlob_BYTE(offset, &entry->label, blob);
2468 	Trspi_UnloadBlob_UINT32(offset, &entry->verificationCount, blob);
2469 	Trspi_UnloadBlob_BOOL(offset, &entry->enabled, blob);
2470 	Trspi_UnloadBlob_BOOL(offset, &entry->locked, blob);
2471 }
2472 
2473 void
2474 Trspi_LoadBlob_TSS_FAMILY_TABLE_ENTRY(UINT64 *offset, BYTE *blob, TSS_FAMILY_TABLE_ENTRY *entry)
2475 {
2476 	Trspi_LoadBlob_UINT32(offset, entry->familyID, blob);
2477 	Trspi_LoadBlob_BYTE(offset, entry->label, blob);
2478 	Trspi_LoadBlob_UINT32(offset, entry->verificationCount, blob);
2479 	Trspi_LoadBlob_BOOL(offset, entry->enabled, blob);
2480 	Trspi_LoadBlob_BOOL(offset, entry->locked, blob);
2481 }
2482 
2483 TSS_RESULT
2484 Trspi_UnloadBlob_TSS_PCR_INFO_SHORT(UINT64 *offset, BYTE *blob, TSS_PCR_INFO_SHORT *pcr)
2485 {
2486 	if (!pcr) {
2487 		UINT32 sizeOfSelect, sizeOfDigestAtRelease;
2488 
2489 		Trspi_UnloadBlob_UINT32(offset, &sizeOfSelect, blob);
2490 		(void)Trspi_UnloadBlob(offset, sizeOfSelect, blob, NULL);
2491 		Trspi_UnloadBlob_BYTE(offset, NULL, blob);
2492 		Trspi_UnloadBlob_UINT32(offset, &sizeOfDigestAtRelease, blob);
2493 		(void)Trspi_UnloadBlob(offset, sizeOfDigestAtRelease, blob, NULL);
2494 
2495 		return TSS_SUCCESS;
2496 	}
2497 
2498 	Trspi_UnloadBlob_UINT32(offset, &pcr->sizeOfSelect, blob);
2499 	if (pcr->sizeOfSelect > 0) {
2500 		pcr->selection = malloc(pcr->sizeOfSelect);
2501 		if (pcr->selection == NULL) {
2502 			LogError("malloc of %u bytes failed.", pcr->sizeOfSelect);
2503 			return TSPERR(TSS_E_OUTOFMEMORY);
2504 		}
2505 		Trspi_UnloadBlob(offset, pcr->sizeOfSelect, blob, pcr->selection);
2506 	} else {
2507 		pcr->selection = NULL;
2508 	}
2509 	Trspi_UnloadBlob_BYTE(offset, &pcr->localityAtRelease, blob);
2510 	Trspi_UnloadBlob_UINT32(offset, &pcr->sizeOfDigestAtRelease, blob);
2511 	if (pcr->sizeOfDigestAtRelease > 0) {
2512 		pcr->digestAtRelease = malloc(pcr->sizeOfDigestAtRelease);
2513 		if (pcr->digestAtRelease == NULL) {
2514 			LogError("malloc of %u bytes failed.", pcr->sizeOfDigestAtRelease);
2515 			free(pcr->selection);
2516 			return TSPERR(TSS_E_OUTOFMEMORY);
2517 		}
2518 		Trspi_UnloadBlob(offset, pcr->sizeOfDigestAtRelease, blob, pcr->digestAtRelease);
2519 	} else {
2520 		pcr->digestAtRelease = NULL;
2521 	}
2522 
2523 	return TSS_SUCCESS;
2524 }
2525 
2526 void
2527 Trspi_LoadBlob_TSS_PCR_INFO_SHORT(UINT64 *offset, BYTE *blob, TSS_PCR_INFO_SHORT *pcr)
2528 {
2529 	Trspi_LoadBlob_UINT32(offset, pcr->sizeOfSelect, blob);
2530 	Trspi_LoadBlob(offset, pcr->sizeOfSelect, blob, pcr->selection);
2531 	Trspi_LoadBlob_BYTE(offset, pcr->localityAtRelease, blob);
2532 	Trspi_LoadBlob_UINT32(offset, pcr->sizeOfDigestAtRelease, blob);
2533 	Trspi_LoadBlob(offset, pcr->sizeOfDigestAtRelease, blob, pcr->digestAtRelease);
2534 }
2535 
2536 TSS_RESULT
2537 Trspi_UnloadBlob_TSS_DELEGATION_TABLE_ENTRY(UINT64 *offset, BYTE *blob,
2538 					    TSS_DELEGATION_TABLE_ENTRY *entry)
2539 {
2540 	TSS_RESULT result;
2541 
2542 	if (!entry) {
2543 		Trspi_UnloadBlob_UINT32(offset, NULL, blob);
2544 		Trspi_UnloadBlob_BYTE(offset, NULL, blob);
2545 		(void)Trspi_UnloadBlob_TSS_PCR_INFO_SHORT(offset, blob, NULL);
2546 		Trspi_UnloadBlob_UINT32(offset, NULL, blob);
2547 		Trspi_UnloadBlob_UINT32(offset, NULL, blob);
2548 		Trspi_UnloadBlob_UINT32(offset, NULL, blob);
2549 		Trspi_UnloadBlob_UINT32(offset, NULL, blob);
2550 
2551 		return TSS_SUCCESS;
2552 	}
2553 
2554 	Trspi_UnloadBlob_UINT32(offset, &entry->tableIndex, blob);
2555 	Trspi_UnloadBlob_BYTE(offset, &entry->label, blob);
2556 	if ((result = Trspi_UnloadBlob_TSS_PCR_INFO_SHORT(offset, blob, &entry->pcrInfo)))
2557 		return result;
2558 	Trspi_UnloadBlob_UINT32(offset, &entry->per1, blob);
2559 	Trspi_UnloadBlob_UINT32(offset, &entry->per2, blob);
2560 	Trspi_UnloadBlob_UINT32(offset, &entry->familyID, blob);
2561 	Trspi_UnloadBlob_UINT32(offset, &entry->verificationCount, blob);
2562 
2563 	return TSS_SUCCESS;
2564 }
2565 
2566 void
2567 Trspi_LoadBlob_TSS_DELEGATION_TABLE_ENTRY(UINT64 *offset, BYTE *blob,
2568 					  TSS_DELEGATION_TABLE_ENTRY *entry)
2569 {
2570 	Trspi_LoadBlob_UINT32(offset, entry->tableIndex, blob);
2571 	Trspi_LoadBlob_BYTE(offset, entry->label, blob);
2572 	Trspi_LoadBlob_TSS_PCR_INFO_SHORT(offset, blob, &entry->pcrInfo);
2573 	Trspi_LoadBlob_UINT32(offset, entry->per1, blob);
2574 	Trspi_LoadBlob_UINT32(offset, entry->per2, blob);
2575 	Trspi_LoadBlob_UINT32(offset, entry->familyID, blob);
2576 	Trspi_LoadBlob_UINT32(offset, entry->verificationCount, blob);
2577 }
2578 
2579 TSS_RESULT
2580 Trspi_UnloadBlob_PCR_COMPOSITE(UINT64 *offset, BYTE *blob, TCPA_PCR_COMPOSITE *out)
2581 {
2582 	TSS_RESULT result;
2583 
2584 	if (!out) {
2585 		UINT32 valueSize;
2586 
2587 		Trspi_UnloadBlob_PCR_SELECTION(offset, blob, NULL);
2588 		Trspi_UnloadBlob_UINT32(offset, &valueSize, blob);
2589 		Trspi_UnloadBlob(offset, valueSize, blob, NULL);
2590 
2591 		return TSS_SUCCESS;
2592 	}
2593 
2594 	if ((result = Trspi_UnloadBlob_PCR_SELECTION(offset, blob, &out->select)))
2595 		return result;
2596 
2597 	Trspi_UnloadBlob_UINT32(offset, &out->valueSize, blob);
2598 	out->pcrValue = malloc(out->valueSize);
2599 	if (out->pcrValue == NULL) {
2600 		LogError("malloc of %u bytes failed.", out->valueSize);
2601 		return TSPERR(TSS_E_OUTOFMEMORY);
2602 	}
2603 	Trspi_UnloadBlob(offset, out->valueSize, blob, (BYTE *)out->pcrValue);
2604 
2605 	return TSS_SUCCESS;
2606 }
2607 
2608 TSS_RESULT
2609 Trspi_UnloadBlob_MIGRATIONKEYAUTH(UINT64 *offset, BYTE *blob, TPM_MIGRATIONKEYAUTH *migAuth)
2610 {
2611 	TSS_RESULT result;
2612 
2613 	if (!migAuth) {
2614 		(void)Trspi_UnloadBlob_PUBKEY(offset, blob, NULL);
2615 		Trspi_UnloadBlob_UINT16(offset, NULL, blob);
2616 		Trspi_UnloadBlob_DIGEST(offset, blob, NULL);
2617 
2618 		return TSS_SUCCESS;
2619 	}
2620 
2621 	if ((result = Trspi_UnloadBlob_PUBKEY(offset, blob, &migAuth->migrationKey)))
2622 		return result;
2623 
2624 	Trspi_UnloadBlob_UINT16(offset, &migAuth->migrationScheme, blob);
2625 	Trspi_UnloadBlob_DIGEST(offset, blob, &migAuth->digest);
2626 
2627 	return TSS_SUCCESS;
2628 }
2629 
2630 void
2631 Trspi_LoadBlob_MIGRATIONKEYAUTH(UINT64 *offset, BYTE *blob, TPM_MIGRATIONKEYAUTH *migAuth)
2632 {
2633 	Trspi_LoadBlob_PUBKEY(offset, blob, &migAuth->migrationKey);
2634 	Trspi_LoadBlob_UINT16(offset, migAuth->migrationScheme, blob);
2635 	Trspi_LoadBlob_DIGEST(offset, blob, &migAuth->digest);
2636 }
2637 
2638 void
2639 Trspi_LoadBlob_MSA_COMPOSITE(UINT64 *offset, BYTE *blob, TPM_MSA_COMPOSITE *msaComp)
2640 {
2641 	UINT32 i;
2642 
2643 	Trspi_LoadBlob_UINT32(offset, msaComp->MSAlist, blob);
2644 	for (i = 0; i < msaComp->MSAlist; i++)
2645 		Trspi_LoadBlob_DIGEST(offset, blob, &msaComp->migAuthDigest[i]);
2646 }
2647 
2648 void
2649 Trspi_LoadBlob_CMK_AUTH(UINT64 *offset, BYTE *blob, TPM_CMK_AUTH *cmkAuth)
2650 {
2651 	Trspi_LoadBlob_DIGEST(offset, blob, &cmkAuth->migrationAuthorityDigest);
2652 	Trspi_LoadBlob_DIGEST(offset, blob, &cmkAuth->destinationKeyDigest);
2653 	Trspi_LoadBlob_DIGEST(offset, blob, &cmkAuth->sourceKeyDigest);
2654 }
2655 
2656 TSS_RESULT
2657 Trspi_Hash_MSA_COMPOSITE(Trspi_HashCtx *c, TPM_MSA_COMPOSITE *m)
2658 {
2659 	UINT32 i;
2660 	TPM_DIGEST *digest;
2661 	TSS_RESULT result;
2662 
2663 	result = Trspi_Hash_UINT32(c, m->MSAlist);
2664 	digest = m->migAuthDigest;
2665 	for (i = 0; i < m->MSAlist; i++) {
2666 		result |= Trspi_Hash_DIGEST(c, digest->digest);
2667 		digest++;
2668 	}
2669 
2670 	return result;
2671 }
2672 
2673 TSS_RESULT
2674 Trspi_UnloadBlob_TSS_PLATFORM_CLASS(UINT64 *offset, BYTE *blob, TSS_PLATFORM_CLASS *platClass)
2675 {
2676 	if (!platClass){
2677 		UINT32 classURISize;
2678 
2679 		Trspi_UnloadBlob_UINT32(offset, NULL, blob);
2680 		Trspi_UnloadBlob_UINT32(offset, &classURISize, blob);
2681 		Trspi_UnloadBlob(offset, classURISize, blob, NULL);
2682 
2683 		return TSS_SUCCESS;
2684 	}
2685 	Trspi_UnloadBlob_UINT32(offset, &platClass->platformClassSimpleIdentifier, blob);
2686 	Trspi_UnloadBlob_UINT32(offset, &platClass->platformClassURISize, blob);
2687 
2688 	platClass->pPlatformClassURI = malloc(platClass->platformClassURISize);
2689 	if (platClass->pPlatformClassURI == NULL) {
2690 		LogError("malloc of %u bytes failed.", platClass->platformClassURISize);
2691 		return TSPERR(TSS_E_OUTOFMEMORY);
2692 	}
2693 	Trspi_UnloadBlob(offset, platClass->platformClassURISize, blob,
2694 			 (BYTE *)platClass->pPlatformClassURI);
2695 
2696 	return TSS_SUCCESS;
2697 }
2698 
2699 void
2700 Trspi_LoadBlob_CAP_VERSION_INFO(UINT64 *offset, BYTE *blob, TPM_CAP_VERSION_INFO *v)
2701 {
2702 	Trspi_LoadBlob_UINT16(offset, v->tag, blob);
2703 	Trspi_LoadBlob_TCPA_VERSION(offset, blob, *(TCPA_VERSION *)(&v->version));
2704 	Trspi_LoadBlob_UINT16(offset, v->specLevel, blob);
2705 	Trspi_LoadBlob_BYTE(offset, v->errataRev, blob);
2706 	Trspi_LoadBlob(offset, sizeof(v->tpmVendorID), blob, v->tpmVendorID);
2707 	Trspi_LoadBlob_UINT16(offset, v->vendorSpecificSize, blob);
2708 	Trspi_LoadBlob(offset, v->vendorSpecificSize, blob, v->vendorSpecific);
2709 }
2710 
2711 TSS_RESULT
2712 Trspi_UnloadBlob_CAP_VERSION_INFO(UINT64 *offset, BYTE *blob, TPM_CAP_VERSION_INFO *v)
2713 {
2714 	if (!v) {
2715 		UINT16 vendorSpecificSize;
2716 
2717 		Trspi_UnloadBlob_UINT16(offset, NULL, blob);
2718 		Trspi_UnloadBlob_VERSION(offset, blob, NULL);
2719 		Trspi_UnloadBlob_UINT16(offset, NULL, blob);
2720 		Trspi_UnloadBlob_BYTE(offset, NULL, blob);
2721 		Trspi_UnloadBlob(offset, 4, blob, NULL);
2722 		Trspi_UnloadBlob_UINT16(offset, &vendorSpecificSize, blob);
2723 
2724 		(*offset) += vendorSpecificSize;
2725 
2726 		return TSS_SUCCESS;
2727 	}
2728 
2729 	Trspi_UnloadBlob_UINT16(offset, &v->tag, blob);
2730 	Trspi_UnloadBlob_VERSION(offset, blob, (TCPA_VERSION *)&v->version);
2731 	Trspi_UnloadBlob_UINT16(offset, &v->specLevel, blob);
2732 	Trspi_UnloadBlob_BYTE(offset, &v->errataRev, blob);
2733 	Trspi_UnloadBlob(offset, sizeof(v->tpmVendorID), blob, v->tpmVendorID);
2734 	Trspi_UnloadBlob_UINT16(offset, &v->vendorSpecificSize, blob);
2735 
2736 	if (v->vendorSpecificSize > 0) {
2737 		if ((v->vendorSpecific = malloc(v->vendorSpecificSize)) == NULL) {
2738 			LogError("malloc of %u bytes failed.", v->vendorSpecificSize);
2739 			return TSPERR(TSS_E_OUTOFMEMORY);
2740 		}
2741 
2742 		Trspi_UnloadBlob(offset, v->vendorSpecificSize, blob, v->vendorSpecific);
2743 	} else {
2744 		v->vendorSpecific = NULL;
2745 	}
2746 
2747 	return TSS_SUCCESS;
2748 }
2749 
2750 TSS_RESULT
2751 Trspi_UnloadBlob_NV_INDEX(UINT64 *offset, BYTE *blob, TPM_NV_INDEX *v)
2752 {
2753 	if (!v) {
2754 		Trspi_UnloadBlob_UINT32(offset, NULL, blob);
2755 
2756 		return TSS_SUCCESS;
2757 	}
2758 
2759 	Trspi_UnloadBlob_UINT32(offset, v, blob);
2760 
2761 	return TSS_SUCCESS;
2762 }
2763 
2764 TSS_RESULT
2765 Trspi_UnloadBlob_NV_ATTRIBUTES(UINT64 *offset, BYTE *blob, TPM_NV_ATTRIBUTES *v)
2766 {
2767 	if (!v) {
2768 		Trspi_UnloadBlob_UINT16(offset, NULL, blob);
2769 		Trspi_UnloadBlob_UINT32(offset, NULL, blob);
2770 
2771 		return TSS_SUCCESS;
2772 	}
2773 
2774 	Trspi_UnloadBlob_UINT16(offset, &v->tag, blob);
2775 	Trspi_UnloadBlob_UINT32(offset, &v->attributes, blob);
2776 
2777 	return TSS_SUCCESS;
2778 }
2779 
2780 TSS_RESULT
2781 Trspi_UnloadBlob_NV_DATA_PUBLIC(UINT64 *offset, BYTE *blob, TPM_NV_DATA_PUBLIC *v)
2782 {
2783 	if (!v) {
2784 		Trspi_UnloadBlob_UINT16(offset, NULL, blob);
2785 		Trspi_UnloadBlob_NV_INDEX(offset, blob, NULL);
2786 		Trspi_UnloadBlob_PCR_INFO_SHORT(offset, blob, NULL);
2787 		Trspi_UnloadBlob_PCR_INFO_SHORT(offset, blob, NULL);
2788 		Trspi_UnloadBlob_NV_ATTRIBUTES(offset, blob, NULL);
2789 		Trspi_UnloadBlob_BYTE(offset, NULL, blob);
2790 		Trspi_UnloadBlob_BYTE(offset, NULL, blob);
2791 		Trspi_UnloadBlob_BYTE(offset, NULL, blob);
2792 		Trspi_UnloadBlob_UINT32(offset, NULL, blob);
2793 
2794 		return TSS_SUCCESS;
2795 	}
2796 
2797 	Trspi_UnloadBlob_UINT16(offset, &v->tag, blob);
2798 	Trspi_UnloadBlob_NV_INDEX(offset, blob, &v->nvIndex);
2799 	Trspi_UnloadBlob_PCR_INFO_SHORT(offset, blob, &v->pcrInfoRead);
2800 	Trspi_UnloadBlob_PCR_INFO_SHORT(offset, blob, &v->pcrInfoWrite);
2801 	Trspi_UnloadBlob_NV_ATTRIBUTES(offset, blob, &v->permission);
2802 	Trspi_UnloadBlob_BYTE(offset, &v->bReadSTClear, blob);
2803 	Trspi_UnloadBlob_BYTE(offset, &v->bWriteSTClear, blob);
2804 	Trspi_UnloadBlob_BYTE(offset, &v->bWriteDefine, blob);
2805 	Trspi_UnloadBlob_UINT32(offset, &v->dataSize, blob);
2806 
2807 	return TSS_SUCCESS;
2808 }
2809