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 (container) 207 memcpy(&container[*offset], object, size); 208 (*offset) += (UINT64) size; 209 } 210 211 void 212 UnloadBlob(UINT64 *offset, UINT32 size, BYTE *container, BYTE *object) 213 { 214 if (object) 215 memcpy(object, &container[*offset], size); 216 (*offset) += (UINT64) size; 217 } 218 219 void 220 LoadBlob_Header(UINT16 tag, UINT32 paramSize, UINT32 ordinal, BYTE * blob) 221 { 222 223 UINT16ToArray(tag, &blob[0]); 224 LogData("Header Tag:", tag); 225 UINT32ToArray(paramSize, &blob[2]); 226 LogData("Header ParamSize:", paramSize); 227 UINT32ToArray(ordinal, &blob[6]); 228 LogData("Header Ordinal:", ordinal); 229 #if 0 230 LogInfo("Blob's TPM Ordinal: 0x%x", ordinal); 231 #endif 232 } 233 234 #ifdef TSS_DEBUG 235 TSS_RESULT 236 LogUnloadBlob_Header(BYTE * blob, UINT32 * size, char *file, int line) 237 { 238 TSS_RESULT result; 239 240 UINT16 temp = Decode_UINT16(blob); 241 LogData("UnloadBlob_Tag:", (temp)); 242 *size = Decode_UINT32(&blob[2]); 243 LogData("UnloadBlob_Header, size:", *size); 244 LogData("UnloadBlob_Header, returnCode:", Decode_UINT32(&blob[6])); 245 246 if ((result = Decode_UINT32(&blob[6]))) { 247 LogTPMERR(result, file, line); 248 } 249 250 return result; 251 } 252 #else 253 TSS_RESULT 254 UnloadBlob_Header(BYTE * blob, UINT32 * size) 255 { 256 UINT16 temp = Decode_UINT16(blob); 257 LogData("UnloadBlob_Tag:", (temp)); 258 *size = Decode_UINT32(&blob[2]); 259 LogData("UnloadBlob_Header, size:", *size); 260 LogData("UnloadBlob_Header, returnCode:", Decode_UINT32(&blob[6])); 261 return Decode_UINT32(&blob[6]); 262 } 263 #endif 264 265 void 266 LoadBlob_Auth(UINT64 *offset, BYTE * blob, TPM_AUTH * auth) 267 { 268 LoadBlob_UINT32(offset, auth->AuthHandle, blob); 269 LoadBlob(offset, TCPA_NONCE_SIZE, blob, auth->NonceOdd.nonce); 270 LoadBlob_BOOL(offset, auth->fContinueAuthSession, blob); 271 LoadBlob(offset, TCPA_AUTHDATA_SIZE, blob, (BYTE *)&auth->HMAC); 272 } 273 274 void 275 UnloadBlob_Auth(UINT64 *offset, BYTE * blob, TPM_AUTH * auth) 276 { 277 if (!auth) { 278 UnloadBlob(offset, TCPA_NONCE_SIZE, blob, NULL); 279 UnloadBlob_BOOL(offset, NULL, blob); 280 UnloadBlob(offset, TCPA_DIGEST_SIZE, blob, NULL); 281 282 return; 283 } 284 285 UnloadBlob(offset, TCPA_NONCE_SIZE, blob, auth->NonceEven.nonce); 286 UnloadBlob_BOOL(offset, &auth->fContinueAuthSession, blob); 287 UnloadBlob(offset, TCPA_DIGEST_SIZE, blob, (BYTE *)&auth->HMAC); 288 } 289 290 void 291 UnloadBlob_VERSION(UINT64 *offset, BYTE *blob, TPM_VERSION *out) 292 { 293 if (!out) { 294 *offset += (sizeof(BYTE) * 4); 295 return; 296 } 297 298 UnloadBlob_BYTE(offset, &out->major, blob); 299 UnloadBlob_BYTE(offset, &out->minor, blob); 300 UnloadBlob_BYTE(offset, &out->revMajor, blob); 301 UnloadBlob_BYTE(offset, &out->revMinor, blob); 302 } 303 304 void 305 LoadBlob_VERSION(UINT64 *offset, BYTE *blob, TPM_VERSION *ver) 306 { 307 LoadBlob_BYTE(offset, ver->major, blob); 308 LoadBlob_BYTE(offset, ver->minor, blob); 309 LoadBlob_BYTE(offset, ver->revMajor, blob); 310 LoadBlob_BYTE(offset, ver->revMinor, blob); 311 } 312 313 void 314 UnloadBlob_TCPA_VERSION(UINT64 *offset, BYTE *blob, TCPA_VERSION *out) 315 { 316 if (!out) { 317 *offset += (sizeof(BYTE) * 4); 318 return; 319 } 320 321 UnloadBlob_BYTE(offset, &out->major, blob); 322 UnloadBlob_BYTE(offset, &out->minor, blob); 323 UnloadBlob_BYTE(offset, &out->revMajor, blob); 324 UnloadBlob_BYTE(offset, &out->revMinor, blob); 325 } 326 327 void 328 LoadBlob_TCPA_VERSION(UINT64 *offset, BYTE *blob, TCPA_VERSION *ver) 329 { 330 LoadBlob_BYTE(offset, ver->major, blob); 331 LoadBlob_BYTE(offset, ver->minor, blob); 332 LoadBlob_BYTE(offset, ver->revMajor, blob); 333 LoadBlob_BYTE(offset, ver->revMinor, blob); 334 } 335 336 TSS_RESULT 337 UnloadBlob_KEY_PARMS(UINT64 *offset, BYTE *blob, TCPA_KEY_PARMS *keyParms) 338 { 339 if (!keyParms) { 340 UINT32 parmSize; 341 342 UnloadBlob_UINT32(offset, NULL, blob); 343 UnloadBlob_UINT16(offset, NULL, blob); 344 UnloadBlob_UINT16(offset, NULL, blob); 345 UnloadBlob_UINT32(offset, &parmSize, blob); 346 347 if (parmSize > 0) 348 UnloadBlob(offset, parmSize, blob, NULL); 349 350 return TSS_SUCCESS; 351 } 352 353 UnloadBlob_UINT32(offset, &keyParms->algorithmID, blob); 354 UnloadBlob_UINT16(offset, &keyParms->encScheme, blob); 355 UnloadBlob_UINT16(offset, &keyParms->sigScheme, blob); 356 UnloadBlob_UINT32(offset, &keyParms->parmSize, blob); 357 358 if (keyParms->parmSize == 0) 359 keyParms->parms = NULL; 360 else { 361 keyParms->parms = malloc(keyParms->parmSize); 362 if (keyParms->parms == NULL) { 363 LogError("malloc of %u bytes failed.", keyParms->parmSize); 364 keyParms->parmSize = 0; 365 return TCSERR(TSS_E_OUTOFMEMORY); 366 } 367 368 UnloadBlob(offset, keyParms->parmSize, blob, keyParms->parms); 369 } 370 371 return TSS_SUCCESS; 372 } 373 374 void 375 UnloadBlob_KEY_FLAGS(UINT64 *offset, BYTE *blob, TCPA_KEY_FLAGS *flags) 376 { 377 if (!flags) { 378 UnloadBlob_UINT32(offset, NULL, blob); 379 380 return; 381 } 382 383 UnloadBlob_UINT32(offset, flags, blob); 384 } 385 386 TSS_RESULT 387 UnloadBlob_CERTIFY_INFO(UINT64 *offset, BYTE *blob, TCPA_CERTIFY_INFO *certify) 388 { 389 TSS_RESULT rc; 390 391 if (!certify) { 392 TPM_VERSION version; 393 UINT32 size; 394 395 UnloadBlob_VERSION(offset, blob, &version); 396 UnloadBlob_UINT16(offset, NULL, blob); 397 UnloadBlob_KEY_FLAGS(offset, blob, NULL); 398 UnloadBlob_BOOL(offset, NULL, blob); 399 400 if ((rc = UnloadBlob_KEY_PARMS(offset, blob, NULL))) 401 return rc; 402 403 UnloadBlob(offset, TCPA_DIGEST_SIZE, blob, NULL); 404 UnloadBlob(offset, TCPA_NONCE_SIZE, blob, NULL); 405 UnloadBlob_BOOL(offset, NULL, blob); 406 UnloadBlob_UINT32(offset, &size, blob); 407 408 if (size > 0) 409 UnloadBlob(offset, size, blob, NULL); 410 411 if (Decode_UINT16((BYTE *) &version) == TPM_TAG_CERTIFY_INFO2){ 412 /* This is a TPM_CERTIFY_INFO2 structure. */ 413 /* Read migrationAuthority. */ 414 UnloadBlob_UINT32(offset, &size, blob); 415 if (size > 0) 416 UnloadBlob(offset, size, blob, NULL); 417 } 418 419 return TSS_SUCCESS; 420 } 421 422 UnloadBlob_VERSION(offset, blob, (TPM_VERSION *)&certify->version); 423 UnloadBlob_UINT16(offset, &certify->keyUsage, blob); 424 UnloadBlob_KEY_FLAGS(offset, blob, &certify->keyFlags); 425 UnloadBlob_BOOL(offset, (TSS_BOOL *)&certify->authDataUsage, blob); 426 427 if ((rc = UnloadBlob_KEY_PARMS(offset, blob, &certify->algorithmParms))) 428 return rc; 429 430 UnloadBlob(offset, TCPA_DIGEST_SIZE, blob, certify->pubkeyDigest.digest); 431 UnloadBlob(offset, TCPA_NONCE_SIZE, blob, certify->data.nonce); 432 UnloadBlob_BOOL(offset, (TSS_BOOL *)&certify->parentPCRStatus, blob); 433 UnloadBlob_UINT32(offset, &certify->PCRInfoSize, blob); 434 435 if (certify->PCRInfoSize > 0) { 436 certify->PCRInfo = (BYTE *)malloc(certify->PCRInfoSize); 437 if (certify->PCRInfo == NULL) { 438 LogError("malloc of %u bytes failed.", certify->PCRInfoSize); 439 certify->PCRInfoSize = 0; 440 free(certify->algorithmParms.parms); 441 certify->algorithmParms.parms = NULL; 442 certify->algorithmParms.parmSize = 0; 443 return TCSERR(TSS_E_OUTOFMEMORY); 444 } 445 UnloadBlob(offset, certify->PCRInfoSize, blob, certify->PCRInfo); 446 } else { 447 certify->PCRInfo = NULL; 448 } 449 450 if (Decode_UINT16((BYTE *) &certify->version) == TPM_TAG_CERTIFY_INFO2){ 451 /* This is a TPM_CERTIFY_INFO2 structure. */ 452 /* Read migrationAuthority. */ 453 UINT32 size; 454 UnloadBlob_UINT32(offset, &size, blob); 455 if (size > 0) 456 UnloadBlob(offset, size, blob, NULL); 457 } 458 459 return TSS_SUCCESS; 460 } 461 462 TSS_RESULT 463 UnloadBlob_KEY_HANDLE_LIST(UINT64 *offset, BYTE *blob, TCPA_KEY_HANDLE_LIST *list) 464 { 465 UINT16 i; 466 467 if (!list) { 468 UINT16 size; 469 470 UnloadBlob_UINT16(offset, &size, blob); 471 472 *offset += (size * sizeof(UINT32)); 473 474 return TSS_SUCCESS; 475 } 476 477 UnloadBlob_UINT16(offset, &list->loaded, blob); 478 if (list->loaded == 0) { 479 list->handle = NULL; 480 return TSS_SUCCESS; 481 } 482 483 list->handle = malloc(list->loaded * sizeof (UINT32)); 484 if (list->handle == NULL) { 485 LogError("malloc of %zd bytes failed.", list->loaded * sizeof (UINT32)); 486 list->loaded = 0; 487 return TCSERR(TSS_E_OUTOFMEMORY); 488 } 489 490 for (i = 0; i < list->loaded; i++) 491 UnloadBlob_UINT32(offset, &list->handle[i], blob); 492 493 return TSS_SUCCESS; 494 } 495 496 void 497 LoadBlob_DIGEST(UINT64 *offset, BYTE *blob, TPM_DIGEST *digest) 498 { 499 LoadBlob(offset, TPM_SHA1_160_HASH_LEN, blob, digest->digest); 500 } 501 502 void 503 UnloadBlob_DIGEST(UINT64 *offset, BYTE *blob, TPM_DIGEST *digest) 504 { 505 UnloadBlob(offset, TPM_SHA1_160_HASH_LEN, blob, digest->digest); 506 } 507 508 void 509 LoadBlob_NONCE(UINT64 *offset, BYTE *blob, TPM_NONCE *nonce) 510 { 511 LoadBlob(offset, TCPA_NONCE_SIZE, blob, nonce->nonce); 512 } 513 514 void 515 UnloadBlob_NONCE(UINT64 *offset, BYTE *blob, TPM_NONCE *nonce) 516 { 517 UnloadBlob(offset, TCPA_NONCE_SIZE, blob, nonce->nonce); 518 } 519 520 void 521 LoadBlob_AUTHDATA(UINT64 *offset, BYTE *blob, TPM_AUTHDATA *authdata) 522 { 523 LoadBlob(offset, TPM_SHA1_160_HASH_LEN, blob, authdata->authdata); 524 } 525 526 void 527 UnloadBlob_AUTHDATA(UINT64 *offset, BYTE *blob, TPM_AUTHDATA *authdata) 528 { 529 UnloadBlob(offset, TPM_SHA1_160_HASH_LEN, blob, authdata->authdata); 530 } 531 532