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