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