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