github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/src/tpm2/tpm2_util.cc (about) 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <sys/types.h> 4 #include <sys/stat.h> 5 #include <fcntl.h> 6 #include <unistd.h> 7 #include <string.h> 8 9 #include <tpm20.h> 10 #include <tpm2_lib.h> 11 #include <gflags/gflags.h> 12 13 #include <openssl_helpers.h> 14 15 #include <openssl/rsa.h> 16 #include <openssl/x509.h> 17 #include <openssl/ssl.h> 18 #include <openssl/evp.h> 19 #include <openssl/asn1.h> 20 #include <openssl/err.h> 21 #include <openssl/aes.h> 22 #include <openssl/hmac.h> 23 #include <openssl/rand.h> 24 25 // 26 // Copyright 2015 Google Corporation, All Rights Reserved. 27 // 28 // Licensed under the Apache License, Version 2.0 (the "License"); 29 // you may not use this file except in compliance with the License. 30 // You may obtain a copy of the License at 31 // http://www.apache.org/licenses/LICENSE-2.0 32 // or in the the file LICENSE-2.0.txt in the top level sourcedirectory 33 // Unless required by applicable law or agreed to in writing, software 34 // distributed under the License is distributed on an "AS IS" BASIS, 35 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 36 // See the License for the specific language governing permissions and 37 // limitations under the License 38 // 39 // Portions of this code were derived TPM2.0-TSS published 40 // by Intel under the license set forth in intel_license.txt 41 // and downloaded on or about August 6, 2015. 42 // Portions of this code were derived tboot published 43 // by Intel under the license set forth in intel_license.txt 44 // and downloaded on or about August 6, 2015. 45 // Portions of this code were derived from the crypto utility 46 // published by John Manferdelli under the Apache 2.0 license. 47 // See github.com/jlmucb/crypto. 48 // File: tpm2_util.cc 49 50 51 // Calling sequence 52 // tpm2_util.exe --Commmand=command 53 54 using std::string; 55 56 DEFINE_string(command, "", "command"); 57 DEFINE_int32(numbytes, 16, "numbytes"); 58 DEFINE_int32(num_param, 16, "integer parameter"); 59 DEFINE_string(password, "password", "password"); 60 DEFINE_string(authString, "", "authString"); 61 DEFINE_string(parentAuth, "", "parent auth String"); 62 DEFINE_string(handle, "", "handle"); 63 DEFINE_int32(pcr_num, -1, "integer parameter"); 64 DEFINE_int32(index, -1, "nv index"); 65 DEFINE_int32(nv_slot, 1000, "nv slot"); 66 DEFINE_int32(nv_size, -1, "nv size"); 67 DEFINE_string(parent_public_file, "", "parent public area"); 68 DEFINE_string(public_file, "", "public area"); 69 DEFINE_string(private_file, "", "private public area"); 70 DEFINE_string(creation_data_file, "", "private public area"); 71 DEFINE_string(save_context_file, "", "save(d) context area"); 72 DEFINE_string(decrypt, "", "decrypt flag"); 73 DEFINE_uint64(startHandle, 0x80000000, "start handle range"); 74 75 #ifndef GFLAGS_NS 76 #define GFLAGS_NS google 77 #endif 78 79 int num_tpmutil_ops = 28; 80 std::string tpmutil_ops[] = { 81 "--command=Startup", 82 "--command=Shutdown", 83 "--command=GetCapabilities", 84 "--command=Flushall", 85 "--command=GetRandom", 86 "--command=ReadClock", 87 "--command=CreatePrimary", 88 "--command=Load", 89 "--command=Save", 90 "--command=CreateKey", 91 "--command=ReadPcr", 92 "--command=Unseal", 93 "--command=Quote", 94 "--command=LoadContext", 95 "--command=SaveContext", 96 "--command=FlushContext", 97 "--command=ReadNv", 98 "--command=WriteNv", 99 "--command=DefineSpace", 100 "--command=UndefineSpace", 101 "--command=SealCombinedTest", 102 "--command=QuoteCombinedTest", 103 "--command=DictionaryAttackLockReset", 104 "--command=KeyCombinedTest", 105 "--command=NvCombinedTest", 106 "--command=ContextCombinedTest", 107 "--command=EndorsementCombinedTest", 108 "--command=NvCombinedSessionTest", 109 }; 110 111 // standard buffer size 112 #define MAX_SIZE_PARAMS 4096 113 114 // Combined tests 115 bool Tpm2_SealCombinedTest(LocalTpm& tpm, int pcr_num); 116 bool Tpm2_QuoteCombinedTest(LocalTpm& tpm, int pcr_num); 117 bool Tpm2_KeyCombinedTest(LocalTpm& tpm, int pcr_num); 118 bool Tpm2_NvCombinedTest(LocalTpm& tpm); 119 bool Tpm2_NvCombinedSessionTest(LocalTpm& tpm); 120 bool Tpm2_ContextCombinedTest(LocalTpm& tpm); 121 bool Tpm2_EndorsementCombinedTest(LocalTpm& tpm); 122 123 void PrintOptions() { 124 printf("Permitted operations:\n"); 125 for (int i = 0; i < num_tpmutil_ops; i++) { 126 printf(" tpmutil.exe %s\n", tpmutil_ops[i].c_str()); 127 } 128 return; 129 } 130 131 int main(int an, char** av) { 132 LocalTpm tpm; 133 134 GFLAGS_NS::ParseCommandLineFlags(&an, &av, true); 135 if (!tpm.OpenTpm("/dev/tpm0")) { 136 printf("Can't open tpm\n"); 137 return 1; 138 } 139 140 if (FLAGS_command == "GetCapabilities") { 141 int size = 512; 142 byte buf[512]; 143 if (!Tpm2_GetCapability(tpm, TPM_CAP_TPM_PROPERTIES, FLAGS_startHandle, 144 &size, buf)) { 145 printf("Tpm2_GetCapability failed\n"); 146 } 147 PrintCapabilities(size, buf); 148 } else if (FLAGS_command == "Startup") { 149 if (!Tpm2_Startup(tpm)) { 150 printf("Tpm2_Startup failed\n"); 151 } 152 } else if (FLAGS_command == "Shutdown") { 153 if (!Tpm2_Shutdown(tpm)) { 154 printf("Tpm2_Shutdown failed\n"); 155 } 156 } else if (FLAGS_command == "GetRandom") { 157 byte buf[256]; 158 159 if (FLAGS_numbytes >256) { 160 printf("Can only get up to 256 bytes\n"); 161 goto done; 162 } 163 memset(buf, 0, 256); 164 if (Tpm2_GetRandom(tpm, FLAGS_numbytes, buf)) { 165 printf("Random bytes: "); 166 PrintBytes(FLAGS_numbytes, buf); 167 printf("\n"); 168 } else { 169 printf("GetRandom failed\n"); 170 } 171 } else if (FLAGS_command == "ReadClock") { 172 uint64_t current_time, current_clock; 173 if (Tpm2_ReadClock(tpm, ¤t_time, ¤t_clock)) { 174 printf("time: %lx %lx\n\n", current_time, current_clock); 175 } else { 176 printf("ReadClock failed\n"); 177 } 178 } else if (FLAGS_command == "CreatePrimary") { 179 #if 0 180 TPM_HANDLE handle; 181 TPM2B_PUBLIC pub_out; 182 TPML_PCR_SELECTION pcrSelect; 183 InitSinglePcrSelection(FLAGS_pcr_num, TPM_ALG_SHA1, &pcrSelect); 184 bool sign = true; 185 if (FLAGS_decrypt.size() > 0) 186 sign = false; 187 if (Tpm2_CreatePrimary(tpm, TPM_RH_OWNER, FLAGS_authString, 188 pcrSelect, sign, 189 &handle, &pub_out)) { 190 printf("Tpm2_CreatePrimary succeeds\n"); 191 printf("Public handle: %08x\n", (uint32_t)handle); 192 printf("type: %04x\n", pub_out.publicArea.type); 193 printf("nameAlg: %04x\n", pub_out.publicArea.nameAlg); 194 printf("Attributes: %08x\n", *(uint32_t*) 195 &pub_out.publicArea.objectAttributes); 196 printf("Algorithm: %08x\n", 197 pub_out.publicArea.parameters.rsaDetail.symmetric.algorithm); 198 printf("keySize: %04x\n", pub_out.publicArea.parameters.rsaDetail.keyBits); 199 printf("Modulus: "); 200 PrintBytes(pub_out.publicArea.unique.rsa.size, 201 pub_out.publicArea.unique.rsa.buffer); 202 printf("\n"); 203 } else { 204 printf("CreatePrimary failed\n"); 205 } 206 #endif 207 } else if (FLAGS_command == "Load") { 208 TPM_HANDLE parent_handle = 0x80000000; 209 TPM_HANDLE new_handle; 210 TPM2B_NAME name; 211 if (FLAGS_handle.size() >0 ) { 212 long unsigned t; 213 t = std::stoul(FLAGS_handle.c_str(), nullptr, 16); 214 parent_handle = (TPM_HANDLE) t; 215 } 216 int size_public = 4096; 217 byte inPublic[4096]; 218 int size_private = 4096; 219 byte inPrivate[4096]; 220 bool ok = true; 221 if (!ReadFileIntoBlock(FLAGS_public_file, &size_public, inPublic)) { 222 printf("Can't read public block\n"); 223 ok = false; 224 } 225 if (!ReadFileIntoBlock(FLAGS_private_file, &size_private, inPrivate)) { 226 printf("Can't read public block\n"); 227 ok = false; 228 } 229 if (ok && Tpm2_Load(tpm, parent_handle, FLAGS_parentAuth, size_public, inPublic, 230 size_private, inPrivate, &new_handle, &name)) { 231 printf("Load succeeded, new handle: %08x\n", new_handle); 232 } else { 233 printf("Load failed\n"); 234 } 235 } else if (FLAGS_command == "Save") { 236 if (Tpm2_Save(tpm)) { 237 printf("Save succeeded\n"); 238 } else { 239 printf("Save failed\n"); 240 } 241 } else if (FLAGS_command == "ReadPcr") { 242 uint32_t updateCounter; 243 TPML_PCR_SELECTION pcrSelectOut; 244 TPML_DIGEST values; 245 if (Tpm2_ReadPcr(tpm, FLAGS_pcr_num, &updateCounter, 246 &pcrSelectOut, &values)) { 247 printf("ReadPcr succeeds, updateCounter: %08x\n", updateCounter); 248 printf("Pcr %d :", FLAGS_pcr_num); 249 PrintBytes(values.digests[0].size, values.digests[0].buffer); 250 printf("\n"); 251 } else { 252 printf("ReadPcr failed\n"); 253 } 254 } else if (FLAGS_command == "CreateKey") { 255 #if 0 256 TPM_HANDLE parent_handle; 257 258 TPM2B_CREATION_DATA creation_out; 259 TPM2B_DIGEST digest_out; 260 TPMT_TK_CREATION creation_ticket; 261 int size_public = 4096; 262 byte out_public[4096]; 263 int size_private = 4096; 264 byte out_private[4096]; 265 266 parent_handle = 0x80000000; 267 if (FLAGS_handle.size() > 0 ) { 268 long unsigned t; 269 t = std::stoul(FLAGS_handle.c_str(), nullptr, 16); 270 parent_handle = (TPM_HANDLE) t; 271 } 272 TPML_PCR_SELECTION pcrSelect; 273 InitSinglePcrSelection(FLAGS_pcr_num, TPM_ALG_SHA1, &pcrSelect); 274 bool sign = true; 275 if (FLAGS_decrypt.size() > 0) 276 sign = false; 277 if (Tpm2_CreateKey(tpm, parent_handle, FLAGS_parentAuth, 278 FLAGS_authString, pcrSelect, 279 sign, false, &size_public, out_public, 280 &size_private, out_private, 281 &creation_out, &digest_out, &creation_ticket)) { 282 printf("CreateKey succeeded\n"); 283 printf("Public (%d): ", size_public); 284 PrintBytes(size_public, out_public); 285 printf("\n"); 286 printf("Private (%d): ", size_private); 287 PrintBytes(size_private, out_private); 288 printf("\n"); 289 if (!WriteFileFromBlock(FLAGS_public_file, 290 size_public, out_public)) { 291 printf("Can't write %s, CreateKey failed\n", FLAGS_private_file.c_str()); 292 } else if (!WriteFileFromBlock(FLAGS_private_file, 293 size_private, out_private)){ 294 printf("Can't write %s\n", FLAGS_private_file.c_str()); 295 } else { 296 printf("CreateKey succeeded\n"); 297 } 298 } 299 printf("CreateKey failed\n"); 300 #endif 301 } else if (FLAGS_command == "Unseal") { 302 #if 0 303 TPM_HANDLE item_handle = 0; 304 int out_size = 1024; 305 byte out[1024]; 306 int size_digest = 0; 307 byte digest[64]; 308 if (Tpm2_Unseal(tpm, item_handle, FLAGS_parentAuth, 309 pcrSelector, TPM_ALG_SHA1, size_digest, digest, 310 &out_size, out)) { 311 printf("Unseal succeeded: "); 312 PrintBytes(out_size, out); 313 printf("\n"); 314 } else { 315 printf("Unseal failed\n"); 316 } 317 #endif 318 } else if (FLAGS_command == "Quote") { 319 #if 0 320 int quote_size = 1024; 321 byte quote[1024]; 322 TPM_HANDLE signingHandle = 0; 323 TPMT_SIG_SCHEME scheme; 324 TPML_PCR_SELECTION pcr_selection; 325 int attest_size = 1024; 326 byte attest[1024]; 327 int sig_size = 1024; 328 byte sig[1024]; 329 if (Tpm2_Quote(tpm, signingHandle, quote_size, quote, scheme, pcr_selection, 330 &attest_size, attest, &sig_size, sig)) { 331 printf("Quote succeeded\n"); 332 } else { 333 printf("Quote failed\n"); 334 } 335 #endif 336 } else if (FLAGS_command == "UndefineSpace") { 337 TPM_HANDLE nv_handle = GetNvHandle(FLAGS_nv_slot); 338 339 if (FLAGS_nv_slot < 0) { 340 printf("Invalid index\n"); 341 } else if (!Tpm2_UndefineSpace(tpm, TPM_RH_OWNER, nv_handle)) { 342 printf("UndefineSpace succeeded\n"); 343 } else { 344 printf("UndefineSpace failed\n"); 345 } 346 } else if (FLAGS_command == "DefineSpace") { 347 TPM_HANDLE nv_handle = GetNvHandle(FLAGS_nv_slot); 348 uint16_t size_data = (uint16_t) FLAGS_nv_size; 349 if (Tpm2_DefineSpace(tpm, TPM_RH_OWNER, nv_handle, FLAGS_authString, 350 0, nullptr, NV_AUTHWRITE | NV_AUTHREAD, size_data)) { 351 printf("DefineSpace succeeded\n"); 352 } else { 353 printf("DefineSpace failed\n"); 354 } 355 } else if (FLAGS_command == "LoadContext") { 356 int size = 4096; 357 byte saveArea[4096]; 358 memset(saveArea, 0, 4096); 359 TPM_HANDLE handle = 0; 360 361 if (!ReadFileIntoBlock(FLAGS_save_context_file, &size, saveArea)) { 362 printf("Can't read %s, LoadContext failed\n", FLAGS_save_context_file.c_str()); 363 } else if (Tpm2_LoadContext(tpm, size, saveArea, &handle)) { 364 printf("LoadContext succeeded\n"); 365 } else { 366 printf("LoadContext failed\n"); 367 } 368 } else if (FLAGS_command == "SaveContext") { 369 uint16_t size = 4096; 370 byte saveArea[4096]; 371 memset(saveArea, 0, 4096); 372 373 TPM_HANDLE handle = 0x80000000; 374 if (FLAGS_handle.size() > 0 ) { 375 long unsigned t; 376 t = std::stoul(FLAGS_handle.c_str(), nullptr, 16); 377 handle = (TPM_HANDLE) t; 378 } else if (Tpm2_SaveContext(tpm, handle, &size, saveArea)) { 379 if (!WriteFileFromBlock(FLAGS_save_context_file, size, saveArea)) { 380 printf("Can't write %s, SaveContext failed\n", FLAGS_save_context_file.c_str()); 381 } else { 382 printf("SaveContext successful\n"); 383 } 384 } else { 385 printf("SaveContext failed\n"); 386 } 387 } else if (FLAGS_command == "FlushContext") { 388 TPM_HANDLE handle = 0x80000000; 389 if (FLAGS_handle.size() >0 ) { 390 long unsigned t; 391 t = std::stoul(FLAGS_handle.c_str(), nullptr, 16); 392 handle = (TPM_HANDLE) t; 393 } 394 if (Tpm2_FlushContext(tpm, handle)) { 395 printf("FlushContext succeeded\n"); 396 } else { 397 printf("FlushContext failed\n"); 398 } 399 } else if (FLAGS_command == "Tpm2_Read_Nv") { 400 TPMI_RH_NV_INDEX index = (TPMI_RH_NV_INDEX) FLAGS_index; 401 uint16_t size_data = 16; 402 byte data[1024]; 403 if (Tpm2_ReadNv(tpm, index, FLAGS_authString, &size_data, data)) { 404 printf("Tpm2_Read_Nv succeeded\n"); 405 PrintBytes(size_data, data); 406 printf("\n"); 407 } else { 408 printf("Tpm2_Read_Nv failed\n"); 409 } 410 } else if (FLAGS_command == "Tpm2_Write_Nv") { 411 TPMI_RH_NV_INDEX index = (TPMI_RH_NV_INDEX) FLAGS_index; 412 int size_data = 0; 413 byte data[1024]; 414 if (Tpm2_WriteNv(tpm, index, FLAGS_authString, size_data, data)) { 415 printf("Tpm2_Write_Nv succeeded\n"); 416 } else { 417 printf("Tpm2_Write_Nv failed\n"); 418 } 419 } else if (FLAGS_command == "Flushall") { 420 if (Tpm2_Flushall(tpm, FLAGS_startHandle)) { 421 printf("Flushall succeeded\n"); 422 } else { 423 printf("Flushall failed\n"); 424 } 425 } else if (FLAGS_command == "KeyCombinedTest") { 426 if (Tpm2_KeyCombinedTest(tpm, FLAGS_pcr_num)) { 427 printf("Tpm2_KeyCombinedTest succeeded\n"); 428 } else { 429 printf("Tpm2_KeyCombinedTest failed\n"); 430 } 431 } else if (FLAGS_command == "SealCombinedTest") { 432 if (Tpm2_SealCombinedTest(tpm, FLAGS_pcr_num)) { 433 printf("SealCombinedTest succeeded\n"); 434 } else { 435 printf("SealCombinedTest failed\n"); 436 } 437 } else if (FLAGS_command == "QuoteCombinedTest") { 438 if (Tpm2_QuoteCombinedTest(tpm, FLAGS_pcr_num)) { 439 printf("QuoteCombinedTest succeeded\n"); 440 } else { 441 printf("QuoteCombinedTest failed\n"); 442 } 443 } else if (FLAGS_command == "NvCombinedTest") { 444 if (Tpm2_NvCombinedTest(tpm)) { 445 printf("NvCombinedTest succeeded\n"); 446 } else { 447 printf("NvCombinedTest failed\n"); 448 } 449 } else if (FLAGS_command == "NvCombinedSessionTest") { 450 if (Tpm2_NvCombinedSessionTest(tpm)) { 451 printf("NvCombinedSessionTest succeeded\n"); 452 } else { 453 printf("NvCombinedSessionTest failed\n"); 454 } 455 } else if (FLAGS_command == "ContextCombinedTest") { 456 if (Tpm2_ContextCombinedTest(tpm)) { 457 printf("ContextCombinedTest succeeded\n"); 458 } else { 459 printf("ContextCombinedTest failed\n"); 460 } 461 } else if (FLAGS_command == "EndorsementCombinedTest") { 462 if (Tpm2_EndorsementCombinedTest(tpm)) { 463 printf("EndorsementCombinedTest succeeded\n"); 464 } else { 465 printf("EndorsementCombinedTest failed\n"); 466 } 467 } else if (FLAGS_command == "DictionaryAttackLockReset") { 468 if (Tpm2_DictionaryAttackLockReset(tpm)) { 469 printf("Tpm2_DictionaryAttackLockReset succeeded\n"); 470 } else { 471 printf("Tpm2_DictionaryAttackLockReset failed\n"); 472 } 473 } else { 474 printf("Invalid command\n"); 475 PrintOptions(); 476 } 477 done: 478 tpm.CloseTpm(); 479 } 480 481 // Combined tests 482 483 bool Tpm2_EndorsementCombinedTest(LocalTpm& tpm) { 484 string authString("01020304"); 485 string parentAuth("01020304"); 486 string emptyAuth; 487 488 TPM_HANDLE ekHandle; 489 TPM2B_PUBLIC pub_out; 490 TPM2B_NAME pub_name; 491 TPM2B_NAME qualified_pub_name; 492 uint16_t pub_blob_size = 1024; 493 byte pub_blob[1024]; 494 495 TPML_PCR_SELECTION pcrSelect; 496 memset((void*)&pcrSelect, 0, sizeof(TPML_PCR_SELECTION)); 497 498 // TPM_RH_ENDORSEMENT 499 TPMA_OBJECT primary_flags; 500 *(uint32_t*)(&primary_flags) = 0; 501 primary_flags.fixedTPM = 1; 502 primary_flags.fixedParent = 1; 503 primary_flags.sensitiveDataOrigin = 1; 504 primary_flags.userWithAuth = 1; 505 primary_flags.decrypt = 1; 506 primary_flags.restricted = 1; 507 508 if (Tpm2_CreatePrimary(tpm, TPM_RH_ENDORSEMENT, emptyAuth, pcrSelect, 509 TPM_ALG_RSA, TPM_ALG_SHA256, primary_flags, 510 TPM_ALG_AES, 128, TPM_ALG_CFB, TPM_ALG_NULL, 511 2048, 0x010001, &ekHandle, &pub_out)) { 512 printf("CreatePrimary succeeded parent: %08x\n", ekHandle); 513 } else { 514 printf("CreatePrimary failed\n"); 515 return false; 516 } 517 if (Tpm2_ReadPublic(tpm, ekHandle, &pub_blob_size, pub_blob, 518 &pub_out, &pub_name, &qualified_pub_name)) { 519 printf("ReadPublic succeeded\n"); 520 } else { 521 printf("ReadPublic failed\n"); 522 return false; 523 } 524 printf("Public blob: "); 525 PrintBytes(pub_blob_size, pub_blob); 526 printf("\n"); 527 printf("Name: "); 528 PrintBytes(pub_name.size, pub_name.name); 529 printf("\n"); 530 printf("Qualified name: "); 531 PrintBytes(qualified_pub_name.size, qualified_pub_name.name); 532 printf("\n"); 533 534 TPM_HANDLE parentHandle; 535 TPM_HANDLE activeHandle; 536 TPM2B_PUBLIC parent_pub_out; 537 TPML_PCR_SELECTION parent_pcrSelect; 538 InitSinglePcrSelection(7, TPM_ALG_SHA1, &parent_pcrSelect); 539 540 TPMA_OBJECT parent_flags; 541 *(uint32_t*)(&parent_flags) = 0; 542 parent_flags.fixedTPM = 1; 543 parent_flags.fixedParent = 1; 544 parent_flags.sensitiveDataOrigin = 1; 545 parent_flags.userWithAuth = 1; 546 parent_flags.decrypt = 1; 547 parent_flags.restricted = 1; 548 549 if (Tpm2_CreatePrimary(tpm, TPM_RH_OWNER, authString, parent_pcrSelect, 550 TPM_ALG_RSA, TPM_ALG_SHA256, parent_flags, 551 TPM_ALG_AES, 128, TPM_ALG_CFB, TPM_ALG_NULL, 552 1024, 0x010001, 553 &parentHandle, &parent_pub_out)) { 554 printf("CreatePrimary succeeded\n"); 555 } else { 556 printf("CreatePrimary failed\n"); 557 return false; 558 } 559 TPM2B_CREATION_DATA creation_out; 560 TPM2B_DIGEST digest_out; 561 TPMT_TK_CREATION creation_ticket; 562 int size_public = MAX_SIZE_PARAMS; 563 byte out_public[MAX_SIZE_PARAMS]; 564 int size_private = MAX_SIZE_PARAMS; 565 byte out_private[MAX_SIZE_PARAMS]; 566 567 memset((void*)&pub_out, 0, sizeof(TPM2B_PUBLIC)); 568 569 TPMA_OBJECT active_flags; 570 *(uint32_t*)(&active_flags) = 0; 571 active_flags.fixedTPM = 1; 572 active_flags.fixedParent = 1; 573 active_flags.sensitiveDataOrigin = 1; 574 active_flags.userWithAuth = 1; 575 active_flags.sign = 1; 576 577 if (Tpm2_CreateKey(tpm, parentHandle, parentAuth, authString, 578 parent_pcrSelect, 579 TPM_ALG_RSA, TPM_ALG_SHA256, active_flags, TPM_ALG_NULL, 580 (TPMI_AES_KEY_BITS)0, TPM_ALG_ECB, TPM_ALG_RSASSA, 581 1024, 0x010001, &size_public, out_public, 582 &size_private, out_private, 583 &creation_out, &digest_out, &creation_ticket)) { 584 printf("Create succeeded private size: %d, public size: %d\n", 585 size_private, size_public); 586 } else { 587 printf("Create failed\n"); 588 return false; 589 } 590 591 if (Tpm2_Load(tpm, parentHandle, parentAuth, size_public, out_public, 592 size_private, out_private, &activeHandle, &pub_name)) { 593 printf("Load succeeded, handle: %08x\n", activeHandle); 594 } else { 595 Tpm2_FlushContext(tpm, ekHandle); 596 Tpm2_FlushContext(tpm, parentHandle); 597 printf("Load failed\n"); 598 return false; 599 } 600 601 TPM2B_DIGEST credential; 602 TPM2B_ID_OBJECT credentialBlob; 603 TPM2B_ENCRYPTED_SECRET secret; 604 TPM2B_DIGEST recovered_credential; 605 606 memset((void*)&credential, 0, sizeof(TPM2B_DIGEST)); 607 memset((void*)&secret, 0, sizeof(TPM2B_ENCRYPTED_SECRET)); 608 memset((void*)&credentialBlob, 0, sizeof(TPM2B_ID_OBJECT)); 609 credential.size = 20; 610 for (int i = 0; i < 20; i++) 611 credential.buffer[i] = i + 1; 612 613 TPM2B_PUBLIC active_pub_out; 614 TPM2B_NAME active_pub_name; 615 TPM2B_NAME active_qualified_pub_name; 616 uint16_t active_pub_blob_size = 1024; 617 byte active_pub_blob[1024]; 618 619 memset((void*)&active_pub_out, 0, sizeof(TPM2B_PUBLIC)); 620 621 if (Tpm2_ReadPublic(tpm, activeHandle, 622 &active_pub_blob_size, active_pub_blob, 623 &active_pub_out, &active_pub_name, 624 &active_qualified_pub_name)) { 625 printf("ReadPublic succeeded\n"); 626 } else { 627 printf("ReadPublic failed\n"); 628 return false; 629 } 630 printf("Active Name (%d): ", active_pub_name.size); 631 PrintBytes(active_pub_name.size, active_pub_name.name); 632 printf("\n"); 633 634 if (Tpm2_MakeCredential(tpm, ekHandle, credential, active_pub_name, 635 &credentialBlob, &secret)) { 636 printf("MakeCredential succeeded\n"); 637 } else { 638 Tpm2_FlushContext(tpm, parentHandle); 639 printf("MakeCredential failed\n"); 640 Tpm2_FlushContext(tpm, activeHandle); 641 Tpm2_FlushContext(tpm, parentHandle); 642 Tpm2_FlushContext(tpm, ekHandle); 643 return false; 644 } 645 printf("credBlob size: %d\n", credentialBlob.size); 646 printf("secret size: %d\n", secret.size); 647 if (Tpm2_ActivateCredential(tpm, activeHandle, ekHandle, 648 parentAuth, emptyAuth, 649 credentialBlob, secret, 650 &recovered_credential)) { 651 printf("ActivateCredential succeeded\n"); 652 printf("Recovered credential (%d): ", recovered_credential.size); 653 PrintBytes(recovered_credential.size, recovered_credential.buffer); 654 printf("\n"); 655 } else { 656 Tpm2_FlushContext(tpm, parentHandle); 657 printf("ActivateCredential failed\n"); 658 Tpm2_FlushContext(tpm, activeHandle); 659 Tpm2_FlushContext(tpm, parentHandle); 660 Tpm2_FlushContext(tpm, ekHandle); 661 return false; 662 } 663 Tpm2_FlushContext(tpm, activeHandle); 664 Tpm2_FlushContext(tpm, parentHandle); 665 Tpm2_FlushContext(tpm, ekHandle); 666 return true; 667 } 668 669 bool Tpm2_ContextCombinedTest(LocalTpm& tpm) { 670 TPM_HANDLE handle; 671 uint16_t size = 4096; 672 byte saveArea[4096]; 673 string authString("01020304"); 674 675 TPM2B_PUBLIC pub_out; 676 TPML_PCR_SELECTION pcrSelect; 677 InitSinglePcrSelection(7, TPM_ALG_SHA1, &pcrSelect); 678 679 TPMA_OBJECT primary_flags; 680 *(uint32_t*)(&primary_flags) = 0; 681 primary_flags.fixedTPM = 1; 682 primary_flags.fixedParent = 1; 683 primary_flags.sensitiveDataOrigin = 1; 684 primary_flags.userWithAuth = 1; 685 primary_flags.sign = 1; 686 687 if (Tpm2_CreatePrimary(tpm, TPM_RH_OWNER, authString, pcrSelect, 688 TPM_ALG_RSA, TPM_ALG_SHA1, primary_flags, TPM_ALG_NULL, 689 (TPMI_AES_KEY_BITS)0, TPM_ALG_ECB, TPM_ALG_RSASSA, 690 1024, 0x010001, 691 &handle, &pub_out)) { 692 printf("CreatePrimary succeeded\n"); 693 } else { 694 printf("CreatePrimary failed\n"); 695 return false; 696 } 697 if (Tpm2_SaveContext(tpm, handle, &size, saveArea)) { 698 printf("Tpm2_SaveContext succeeds, save area %d\n", size); 699 } else { 700 printf("Tpm2_SaveContext failed\n"); 701 return false; 702 } 703 if (Tpm2_FlushContext(tpm, handle)) { 704 printf("Tpm2_FlushContext succeeds, save area %d\n", size); 705 } else { 706 printf("Tpm2_FlushContext failed\n"); 707 return false; 708 } 709 handle = 0; 710 if (Tpm2_LoadContext(tpm, size, saveArea, &handle)) { 711 printf("Tpm2_LoadContext succeeds, handle: %08x, save area %d\n", 712 handle, size); 713 } else { 714 printf("Tpm2_LoadContext failed\n"); 715 return false; 716 } 717 Tpm2_FlushContext(tpm, handle); 718 return true; 719 } 720 721 bool Tpm2_NvCombinedTest(LocalTpm& tpm) { 722 int slot = 1000; 723 string authString("01020304"); 724 uint16_t size_data = 16; 725 byte data_in[512] = { 726 0x9, 0x8, 0x7, 0x6, 727 0x9, 0x8, 0x7, 0x6, 728 0x9, 0x8, 0x7, 0x6, 729 0x9, 0x8, 0x7, 0x6 730 }; 731 uint16_t size_out = 512; 732 byte data_out[512]; 733 TPM_HANDLE nv_handle = GetNvHandle(slot); 734 735 if (Tpm2_UndefineSpace(tpm, TPM_RH_OWNER, nv_handle)) { 736 printf("Tpm2_UndefineSpace %d succeeds\n", slot); 737 } else { 738 printf("Tpm2_UndefineSpace fails (but that's OK usually)\n"); 739 } 740 if (Tpm2_DefineSpace(tpm, TPM_RH_OWNER, nv_handle, authString, 0, nullptr, 741 NV_AUTHWRITE | NV_AUTHREAD, size_data) ) { 742 printf("Tpm2_DefineSpace %d succeeds\n", nv_handle); 743 } else { 744 printf("Tpm2_DefineSpace fails\n"); 745 return false; 746 } 747 if (Tpm2_WriteNv(tpm, nv_handle, authString, size_data, data_in)) { 748 printf("Tpm2_WriteNv %d succeeds, %d bytes written\n", nv_handle, size_data); 749 } else { 750 printf("Tpm2_WriteNv fails\n"); 751 return false; 752 } 753 size_out = size_data; 754 if (Tpm2_ReadNv(tpm, nv_handle, authString, &size_out, data_out)) { 755 printf("Tpm2_ReadNv %d succeeds: ", nv_handle); 756 PrintBytes(size_out, data_out); 757 printf("\n"); 758 } else { 759 printf("Tpm2_ReadNv fails\n"); 760 return false; 761 } 762 763 size_data = 8; 764 memset(data_out, 0, 16); 765 // Counter tests 766 printf("\n\nCounter tests\n"); 767 if (Tpm2_UndefineSpace(tpm, TPM_RH_OWNER, nv_handle)) { 768 printf("Tpm2_UndefineSpace %d succeeds\n", slot); 769 } else { 770 printf("Tpm2_UndefineSpace fails (but that's OK usually)\n"); 771 } 772 // Should be AuthRead, AuthWrite, Counter, Sha256 773 if (Tpm2_DefineSpace(tpm, TPM_RH_OWNER, nv_handle, authString, 0, nullptr, 774 NV_COUNTER | NV_AUTHWRITE | NV_AUTHREAD, 8)) { 775 printf("Tpm2_DefineSpace %d succeeds\n", nv_handle); 776 } else { 777 printf("Tpm2_DefineSpace fails\n"); 778 return false; 779 } 780 if (Tpm2_IncrementNv(tpm, nv_handle, authString)) { 781 printf("Tpm2_IncrementNv succeeds\n"); 782 } else { 783 printf("Tpm2_IncrementNv fails\n"); 784 } 785 size_out = size_data; 786 if (Tpm2_ReadNv(tpm, nv_handle, authString, &size_out, data_out)) { 787 printf("Tpm2_ReadNv succeeds\n"); 788 printf("Counter value: "); PrintBytes(size_out, data_out); printf("\n"); 789 } else { 790 printf("Tpm2_ReadNv fails\n"); 791 } 792 if (Tpm2_IncrementNv(tpm, nv_handle, authString)) { 793 printf("Tpm2_IncrementNv succeeds\n"); 794 } else { 795 printf("Tpm2_IncrementNv fails\n"); 796 } 797 if (Tpm2_ReadNv(tpm, nv_handle, authString, &size_out, data_out)) { 798 printf("Tpm2_ReadNv succeeds\n"); 799 printf("Counter value: "); PrintBytes(size_out, data_out); printf("\n"); 800 } else { 801 printf("Tpm2_ReadNv fails\n"); 802 } 803 if (Tpm2_UndefineSpace(tpm, TPM_RH_OWNER, nv_handle)) { 804 printf("Tpm2_UndefineSpace %d succeeds\n", slot); 805 } else { 806 printf("Tpm2_UndefineSpace fails (but that's OK usually)\n"); 807 } 808 809 return true; 810 } 811 812 bool Tpm2_KeyCombinedTest(LocalTpm& tpm, int pcr_num) { 813 string authString("01020304"); 814 string parentAuth("01020304"); 815 string emptyAuth; 816 817 TPM_HANDLE parent_handle; 818 TPM2B_PUBLIC pub_out; 819 TPML_PCR_SELECTION pcrSelect; 820 InitSinglePcrSelection(pcr_num, TPM_ALG_SHA1, &pcrSelect); 821 822 TPMA_OBJECT primary_flags; 823 *(uint32_t*)(&primary_flags) = 0; 824 primary_flags.fixedTPM = 1; 825 primary_flags.fixedParent = 1; 826 primary_flags.sensitiveDataOrigin = 1; 827 primary_flags.userWithAuth = 1; 828 primary_flags.decrypt = 1; 829 primary_flags.restricted = 1; 830 831 if (Tpm2_CreatePrimary(tpm, TPM_RH_OWNER, authString, pcrSelect, 832 TPM_ALG_RSA, TPM_ALG_SHA1, primary_flags, 833 TPM_ALG_AES, 128, TPM_ALG_CFB, TPM_ALG_NULL, 834 1024, 0x010001, 835 &parent_handle, &pub_out)) { 836 printf("CreatePrimary succeeded\n"); 837 } else { 838 printf("CreatePrimary failed\n"); 839 return false; 840 } 841 TPM2B_CREATION_DATA creation_out; 842 TPM2B_DIGEST digest_out; 843 TPMT_TK_CREATION creation_ticket; 844 int size_public = MAX_SIZE_PARAMS; 845 byte out_public[MAX_SIZE_PARAMS]; 846 int size_private = MAX_SIZE_PARAMS; 847 byte out_private[MAX_SIZE_PARAMS]; 848 849 TPMA_OBJECT create_flags; 850 *(uint32_t*)(&create_flags) = 0; 851 create_flags.fixedTPM = 1; 852 create_flags.fixedParent = 1; 853 create_flags.sensitiveDataOrigin = 1; 854 create_flags.userWithAuth = 1; 855 create_flags.sign = 1; 856 857 if (Tpm2_CreateKey(tpm, parent_handle, parentAuth, authString, pcrSelect, 858 TPM_ALG_RSA, TPM_ALG_SHA1, create_flags, TPM_ALG_NULL, 859 (TPMI_AES_KEY_BITS)0, TPM_ALG_ECB, TPM_ALG_RSASSA, 860 1024, 0x010001, &size_public, out_public, 861 &size_private, out_private, 862 &creation_out, &digest_out, &creation_ticket)) { 863 printf("Create succeeded private size: %d, public size: %d\n", 864 size_private, size_public); 865 } else { 866 printf("Create failed\n"); 867 return false; 868 } 869 870 TPM_HANDLE load_handle = 0; 871 TPM2B_NAME name; 872 if (Tpm2_Load(tpm, parent_handle, parentAuth, size_public, out_public, 873 size_private, out_private, &load_handle, &name)) { 874 printf("Load succeeded, handle: %08x\n", load_handle); 875 } else { 876 Tpm2_FlushContext(tpm, parent_handle); 877 printf("Load failed\n"); 878 return false; 879 } 880 TPM2B_DATA qualifyingData; 881 TPM2B_ATTEST attest; 882 TPMT_SIGNATURE sig; 883 qualifyingData.size = 3; 884 qualifyingData.buffer[0] = 5; 885 qualifyingData.buffer[1] = 6; 886 qualifyingData.buffer[2] = 7; 887 if (Tpm2_Certify(tpm, load_handle, load_handle, 888 parentAuth, parentAuth, 889 qualifyingData, &attest, &sig)) { 890 printf("Certify succeeded\n"); 891 printf("attested (%d): ", attest.size); 892 PrintBytes(attest.size, attest.attestationData); 893 printf("\n"); 894 printf("signature (%d %d %d): ", sig.sigAlg, sig.signature.rsassa.hash, 895 sig.signature.rsassa.sig.size); 896 PrintBytes(sig.signature.rsassa.sig.size, sig.signature.rsassa.sig.buffer); 897 printf("\n"); 898 } else { 899 Tpm2_FlushContext(tpm, load_handle); 900 Tpm2_FlushContext(tpm, parent_handle); 901 printf("Certify failed\n"); 902 return false; 903 } 904 905 // evict Control 906 TPM_HANDLE persistant_handle = 0x810003e8; 907 908 if (!Tpm2_EvictControl(tpm, TPM_RH_OWNER, persistant_handle, 909 authString, persistant_handle)) { 910 printf("Tpm2_EvictControl first evicting fails\n"); 911 } else { 912 printf("Tpm2_EvictControl first evicting succeeds\n"); 913 } 914 915 // make control permanent 916 if (!Tpm2_EvictControl(tpm, TPM_RH_OWNER, load_handle, authString, 917 persistant_handle)) { 918 printf("Tpm2_EvictControl fails\n"); 919 } else { 920 printf("Tpm2_EvictControl succeeds %08x\n", persistant_handle); 921 } 922 923 // evict it again 924 if (!Tpm2_EvictControl(tpm, TPM_RH_OWNER, persistant_handle, 925 authString, persistant_handle)) { 926 printf("Tpm2_EvictControl second evicting fails\n"); 927 } else { 928 printf("Tpm2_EvictControl second evicting succeeds\n"); 929 } 930 931 if (load_handle != 0) 932 Tpm2_FlushContext(tpm, load_handle); 933 Tpm2_FlushContext(tpm, parent_handle); 934 return true; 935 } 936 937 938 bool Tpm2_SealCombinedTest(LocalTpm& tpm, int pcr_num) { 939 string authString("01020304"); 940 string parentAuth("01020304"); 941 string emptyAuth; 942 943 TPM_HANDLE parent_handle; 944 TPM2B_PUBLIC pub_out; 945 TPML_PCR_SELECTION pcrSelect; 946 InitSinglePcrSelection(pcr_num, TPM_ALG_SHA1, &pcrSelect); 947 948 TPMA_OBJECT primary_flags; 949 *(uint32_t*)(&primary_flags) = 0; 950 primary_flags.fixedTPM = 1; 951 primary_flags.fixedParent = 1; 952 primary_flags.sensitiveDataOrigin = 1; 953 primary_flags.userWithAuth = 1; 954 primary_flags.decrypt = 1; 955 primary_flags.restricted = 1; 956 957 if (Tpm2_CreatePrimary(tpm, TPM_RH_OWNER, authString, pcrSelect, 958 TPM_ALG_RSA, TPM_ALG_SHA1, primary_flags, 959 TPM_ALG_AES, 128, TPM_ALG_CFB, TPM_ALG_NULL, 960 1024, 0x010001, 961 &parent_handle, &pub_out)) { 962 printf("CreatePrimary succeeded\n"); 963 } else { 964 printf("CreatePrimary failed\n"); 965 return false; 966 } 967 TPM2B_DIGEST secret; 968 secret.size = 16; 969 for (int i = 0; i < 16; i++) 970 secret.buffer[i] = (byte)(i + 1); 971 972 TPM2B_CREATION_DATA creation_out; 973 TPMT_TK_CREATION creation_ticket; 974 int size_public = MAX_SIZE_PARAMS; 975 byte out_public[MAX_SIZE_PARAMS]; 976 int size_private = MAX_SIZE_PARAMS; 977 byte out_private[MAX_SIZE_PARAMS]; 978 979 TPM2B_DIGEST digest_out; 980 TPM2B_NONCE initial_nonce; 981 TPM2B_ENCRYPTED_SECRET salt; 982 TPMT_SYM_DEF symmetric; 983 TPM_HANDLE session_handle; 984 TPM2B_NONCE nonce_obj; 985 986 initial_nonce.size = 16; 987 memset(initial_nonce.buffer, 0, 16); 988 salt.size = 0; 989 symmetric.algorithm = TPM_ALG_NULL; 990 991 // Start auth session 992 if (Tpm2_StartAuthSession(tpm, TPM_RH_NULL, TPM_RH_NULL, 993 initial_nonce, salt, TPM_SE_POLICY, 994 symmetric, TPM_ALG_SHA1, &session_handle, 995 &nonce_obj)) { 996 printf("Tpm2_StartAuthSession succeeds handle: %08x\n", 997 session_handle); 998 printf("nonce (%d): ", nonce_obj.size); 999 PrintBytes(nonce_obj.size, nonce_obj.buffer); 1000 printf("\n"); 1001 } else { 1002 printf("Tpm2_StartAuthSession fails\n"); 1003 return false; 1004 } 1005 1006 TPM2B_DIGEST policy_digest; 1007 // get policy digest 1008 if(Tpm2_PolicyGetDigest(tpm, session_handle, &policy_digest)) { 1009 printf("PolicyGetDigest before Pcr succeeded: "); 1010 PrintBytes(policy_digest.size, policy_digest.buffer); printf("\n"); 1011 } else { 1012 Tpm2_FlushContext(tpm, session_handle); 1013 printf("PolicyGetDigest failed\n"); 1014 return false; 1015 } 1016 1017 if (Tpm2_PolicyPassword(tpm, session_handle)) { 1018 printf("PolicyPassword succeeded\n"); 1019 } else { 1020 Tpm2_FlushContext(tpm, session_handle); 1021 printf("PolicyPassword failed\n"); 1022 return false; 1023 } 1024 1025 TPM2B_DIGEST expected_digest; 1026 expected_digest.size = 0; 1027 if (Tpm2_PolicyPcr(tpm, session_handle, 1028 expected_digest, pcrSelect)) { 1029 printf("PolicyPcr succeeded\n"); 1030 } else { 1031 printf("PolicyPcr failed\n"); 1032 Tpm2_FlushContext(tpm, session_handle); 1033 return false; 1034 } 1035 1036 if(Tpm2_PolicyGetDigest(tpm, session_handle, &policy_digest)) { 1037 printf("PolicyGetDigest succeeded: "); 1038 PrintBytes(policy_digest.size, policy_digest.buffer); printf("\n"); 1039 } else { 1040 printf("PolicyGetDigest failed\n"); 1041 return false; 1042 } 1043 1044 TPMA_OBJECT create_flags; 1045 *(uint32_t*)(&create_flags) = 0; 1046 create_flags.fixedTPM = 1; 1047 create_flags.fixedParent = 1; 1048 1049 if (Tpm2_CreateSealed(tpm, parent_handle, policy_digest.size, 1050 policy_digest.buffer, parentAuth, secret.size, 1051 secret.buffer, pcrSelect, TPM_ALG_SHA1, create_flags, 1052 TPM_ALG_NULL, (TPMI_AES_KEY_BITS)0, TPM_ALG_ECB, 1053 TPM_ALG_RSASSA, 1024, 0x010001, 1054 &size_public, out_public, &size_private, out_private, 1055 &creation_out, &digest_out, &creation_ticket)) { 1056 printf("Create with digest succeeded private size: %d, public size: %d\n", 1057 size_private, size_public); 1058 } else { 1059 printf("Create with digest failed\n"); 1060 Tpm2_FlushContext(tpm, session_handle); 1061 return false; 1062 } 1063 1064 TPM_HANDLE load_handle; 1065 TPM2B_NAME name; 1066 if (Tpm2_Load(tpm, parent_handle, parentAuth, size_public, out_public, 1067 size_private, out_private, &load_handle, &name)) { 1068 printf("Load succeeded\n"); 1069 } else { 1070 printf("Load failed\n"); 1071 Tpm2_FlushContext(tpm, session_handle); 1072 return false; 1073 } 1074 1075 int unsealed_size = MAX_SIZE_PARAMS; 1076 byte unsealed[MAX_SIZE_PARAMS]; 1077 TPM2B_DIGEST hmac; 1078 hmac.size = 0; 1079 if (!Tpm2_Unseal(tpm, load_handle, parentAuth, session_handle, 1080 nonce_obj, 0x01, hmac, 1081 &unsealed_size, unsealed)) { 1082 printf("Unseal failed\n"); 1083 Tpm2_FlushContext(tpm, session_handle); 1084 Tpm2_FlushContext(tpm, load_handle); 1085 return false; 1086 } 1087 printf("Unseal succeeded, unsealed (%d): ", unsealed_size); 1088 PrintBytes(unsealed_size, unsealed); 1089 printf("\n"); 1090 Tpm2_FlushContext(tpm, session_handle); 1091 Tpm2_FlushContext(tpm, load_handle); 1092 return true; 1093 } 1094 1095 bool Tpm2_QuoteCombinedTest(LocalTpm& tpm, int pcr_num) { 1096 string authString("01020304"); 1097 string parentAuth("01020304"); 1098 string emptyAuth; 1099 1100 TPM_HANDLE parent_handle; 1101 TPM2B_PUBLIC pub_out; 1102 TPML_PCR_SELECTION pcr_selection; 1103 InitSinglePcrSelection(pcr_num, TPM_ALG_SHA1, &pcr_selection); 1104 1105 TPMA_OBJECT primary_flags; 1106 *(uint32_t*)(&primary_flags) = 0; 1107 primary_flags.fixedTPM = 1; 1108 primary_flags.fixedParent = 1; 1109 primary_flags.sensitiveDataOrigin = 1; 1110 primary_flags.userWithAuth = 1; 1111 primary_flags.decrypt = 1; 1112 primary_flags.restricted = 1; 1113 1114 if (Tpm2_CreatePrimary(tpm, TPM_RH_OWNER, authString, pcr_selection, 1115 TPM_ALG_RSA, TPM_ALG_SHA1, primary_flags, 1116 TPM_ALG_AES, 128, TPM_ALG_CFB, TPM_ALG_NULL, 1117 1024, 0x010001, 1118 &parent_handle, &pub_out)) { 1119 printf("CreatePrimary succeeded\n"); 1120 } else { 1121 printf("CreatePrimary failed\n"); 1122 return false; 1123 } 1124 1125 if (pcr_num >= 0) { 1126 uint16_t size_eventData = 3; 1127 byte eventData[3] = {1, 2, 3}; 1128 if (Tpm2_PCR_Event(tpm, pcr_num, size_eventData, eventData)) { 1129 printf("Tpm2_PCR_Event succeeded\n"); 1130 } else { 1131 printf("Tpm2_PCR_Event failed\n"); 1132 } 1133 } 1134 1135 TPM2B_CREATION_DATA creation_out; 1136 TPMT_TK_CREATION creation_ticket; 1137 int size_public = MAX_SIZE_PARAMS; 1138 byte out_public[MAX_SIZE_PARAMS]; 1139 int size_private = MAX_SIZE_PARAMS; 1140 byte out_private[MAX_SIZE_PARAMS]; 1141 TPM2B_DIGEST digest_out; 1142 1143 TPMA_OBJECT create_flags; 1144 *(uint32_t*)(&create_flags) = 0; 1145 create_flags.fixedTPM = 1; 1146 create_flags.fixedParent = 1; 1147 create_flags.sensitiveDataOrigin = 1; 1148 create_flags.userWithAuth = 1; 1149 create_flags.sign = 1; 1150 create_flags.restricted = 1; 1151 1152 if (Tpm2_CreateKey(tpm, parent_handle, parentAuth, authString, pcr_selection, 1153 TPM_ALG_RSA, TPM_ALG_SHA1, create_flags, TPM_ALG_NULL, 1154 (TPMI_AES_KEY_BITS)0, TPM_ALG_ECB, TPM_ALG_RSASSA, 1155 1024, 0x010001, 1156 &size_public, out_public, &size_private, out_private, 1157 &creation_out, &digest_out, &creation_ticket)) { 1158 printf("Create succeeded, private size: %d, public size: %d\n", 1159 size_private, size_public); 1160 } else { 1161 printf("Create failed\n"); 1162 return false; 1163 } 1164 1165 TPM_HANDLE load_handle; 1166 TPM2B_NAME name; 1167 if (Tpm2_Load(tpm, parent_handle, parentAuth, size_public, out_public, 1168 size_private, out_private, &load_handle, &name)) { 1169 printf("Load succeeded\n"); 1170 } else { 1171 printf("Load failed\n"); 1172 return false; 1173 } 1174 1175 TPM2B_DATA to_quote; 1176 to_quote.size = 16; 1177 for (int i = 0; i < 16; i++) 1178 to_quote.buffer[i] = (byte)(i + 1); 1179 TPMT_SIG_SCHEME scheme; 1180 1181 int quote_size = MAX_SIZE_PARAMS; 1182 byte quoted[MAX_SIZE_PARAMS]; 1183 int sig_size = MAX_SIZE_PARAMS; 1184 byte sig[MAX_SIZE_PARAMS]; 1185 if (!Tpm2_Quote(tpm, load_handle, parentAuth, 1186 to_quote.size, to_quote.buffer, 1187 scheme, pcr_selection, TPM_ALG_RSA, TPM_ALG_SHA1, 1188 "e_size, quoted, &sig_size, sig)) { 1189 printf("Quote failed\n"); 1190 Tpm2_FlushContext(tpm, load_handle); 1191 Tpm2_FlushContext(tpm, parent_handle); 1192 return false; 1193 } 1194 printf("Quote succeeded, quoted (%d): ", quote_size); 1195 PrintBytes(quote_size, quoted); 1196 printf("\n"); 1197 printf("Sig (%d): ", sig_size); 1198 PrintBytes(sig_size, sig); 1199 printf("\n"); 1200 Tpm2_FlushContext(tpm, load_handle); 1201 Tpm2_FlushContext(tpm, parent_handle); 1202 return true; 1203 } 1204 1205 1206 void seperate_key_test() { 1207 RSA* rsa_key = RSA_generate_key(2048, 0x010001ULL, nullptr, nullptr); 1208 if (rsa_key == nullptr) { 1209 printf("Can't generate RSA key\n"); 1210 return; 1211 } 1212 TPM2B_DIGEST secret; 1213 TPM2B_ENCRYPTED_SECRET salt; 1214 secret.size = 20; 1215 memcpy(secret.buffer, (byte*)"12345678901234567890", secret.size); 1216 1217 // Encrypt salt 1218 printf("\nencrypting salt\n"); 1219 int size_padded_secret= 256; 1220 byte padded_secret[256]; 1221 RSA_padding_add_PKCS1_OAEP(padded_secret, 256, secret.buffer, secret.size, 1222 (byte*)"SECRET", strlen("SECRET")+1); 1223 int n = RSA_public_encrypt(size_padded_secret, padded_secret, salt.secret, 1224 rsa_key, RSA_NO_PADDING); 1225 salt.size = n; 1226 1227 byte decrypted_with_pad[512]; 1228 byte recovered_secret[512]; 1229 memset(recovered_secret, 0, 512); 1230 memset(decrypted_with_pad, 0, 512); 1231 1232 printf("\nEncrypted salt (%d): ", n); 1233 PrintBytes(n, salt.secret); printf("\n"); 1234 int m = RSA_private_decrypt(n, (byte*) salt.secret, 1235 (byte*)decrypted_with_pad, rsa_key, 1236 RSA_NO_PADDING); 1237 if (m < 0) { 1238 printf("Can't decrypt\n"); 1239 return; 1240 } 1241 printf("decrypted(%d): ", m); 1242 PrintBytes(m, decrypted_with_pad);printf("\n"); 1243 salt.size = m; 1244 int k = 0; 1245 while(k < 256 && decrypted_with_pad[k] == 0) k++; 1246 RSA_padding_check_PKCS1_OAEP(recovered_secret, 256, 1247 &decrypted_with_pad[k], 256-k, 256, 1248 (byte*)"SECRET", strlen("SECRET")+1); 1249 } 1250 1251 // For Jethro 1252 bool Tpm2_NvCombinedSessionTest(LocalTpm& tpm) { 1253 printf("Tpm2_NvCombinedSessionTest\n\n"); 1254 extern int CreatePasswordAuthArea(string& password, int size, byte* buf); 1255 1256 int slot = 1000; 1257 string authString("01020304"); 1258 uint16_t size_data = 8; 1259 uint16_t size_out = 512; 1260 byte data_out[512]; 1261 TPM_HANDLE nv_handle = GetNvHandle(slot); 1262 bool ret = true; 1263 1264 TPM2B_ENCRYPTED_SECRET salt; 1265 TPM_HANDLE sessionHandle = 0; 1266 TPML_PCR_SELECTION pcrSelect; 1267 memset((void*)&pcrSelect, 0, sizeof(TPML_PCR_SELECTION)); 1268 1269 TPM2B_DIGEST secret; 1270 ProtectedSessionAuthInfo authInfo; 1271 TPMT_SYM_DEF symmetric; 1272 1273 authInfo.hash_alg_ = TPM_ALG_SHA1; 1274 int hashSize = SizeHash(authInfo.hash_alg_); 1275 1276 // If encryption. 1277 symmetric.algorithm = TPM_ALG_AES; 1278 symmetric.keyBits.aes = 128; 1279 symmetric.mode.aes = TPM_ALG_CFB; 1280 1281 authInfo.targetAuthValue_.size = authString.size(); 1282 memset(authInfo.targetAuthValue_.buffer, 0, authString.size()); 1283 1284 authInfo.newNonce_.size = hashSize; 1285 authInfo.oldNonce_.size = hashSize; 1286 memset(authInfo.newNonce_.buffer, 0, hashSize); 1287 memset(authInfo.oldNonce_.buffer, 0, hashSize); 1288 RAND_bytes(authInfo.oldNonce_.buffer, authInfo.oldNonce_.size); 1289 1290 memset(secret.buffer, 0, 32); 1291 secret.size = 20; 1292 RAND_bytes(secret.buffer, secret.size); 1293 1294 #if 1 1295 printf("newNonce: "); 1296 PrintBytes(authInfo.newNonce_.size, authInfo.newNonce_.buffer); printf("\n"); 1297 printf("oldNonce: "); 1298 PrintBytes(authInfo.oldNonce_.size, authInfo.oldNonce_.buffer); printf("\n"); 1299 printf("Secret: "); PrintBytes(secret.size, secret.buffer); printf("\n"); 1300 #endif 1301 1302 // Get endorsement key handle 1303 string emptyAuth; 1304 TPM_HANDLE ekHandle; 1305 TPM2B_PUBLIC pub_out; 1306 1307 // TPM_RH_ENDORSEMENT 1308 TPMA_OBJECT primary_flags; 1309 *(uint32_t*)(&primary_flags) = 0; 1310 primary_flags.fixedTPM = 1; 1311 primary_flags.fixedParent = 1; 1312 primary_flags.sensitiveDataOrigin = 1; 1313 primary_flags.userWithAuth = 1; 1314 primary_flags.decrypt = 1; 1315 primary_flags.restricted = 1; 1316 1317 // Get rid of the old counter. 1318 if (Tpm2_UndefineSpace(tpm, TPM_RH_OWNER, nv_handle)) { 1319 printf("Tpm2_UndefineSpace %d succeeds\n", slot); 1320 } else { 1321 printf("Tpm2_UndefineSpace fails (but that's OK usually)\n"); 1322 } 1323 if (Tpm2_DefineSpace(tpm, TPM_RH_OWNER, nv_handle, authString, 1324 0, nullptr, NV_COUNTER | NV_AUTHWRITE | NV_AUTHREAD, 1325 size_data)) { 1326 printf("DefineSpace succeeded\n"); 1327 } else { 1328 printf("DefineSpace failed\n"); 1329 return false; 1330 } 1331 if (Tpm2_IncrementNv(tpm, nv_handle, authString)) { 1332 printf("Initial Tpm2_IncrementNv succeeds\n"); 1333 } else { 1334 printf("Initial Tpm2_IncrementNv fails\n"); 1335 return false; 1336 } 1337 1338 // Get endorsement key. 1339 if (Tpm2_CreatePrimary(tpm, TPM_RH_ENDORSEMENT, emptyAuth, pcrSelect, 1340 TPM_ALG_RSA, TPM_ALG_SHA1, primary_flags, 1341 TPM_ALG_AES, 128, TPM_ALG_CFB, TPM_ALG_NULL, 1342 2048, 0x010001, &ekHandle, &pub_out)) { 1343 printf("CreatePrimary succeeded: %08x\n", ekHandle); 1344 } else { 1345 printf("CreatePrimary failed\n"); 1346 return false; 1347 } 1348 1349 TPM2B_NAME pub_name; 1350 TPM2B_NAME qualified_pub_name; 1351 uint16_t pub_blob_size = 2048; 1352 byte pub_blob[2048]; 1353 1354 if (Tpm2_ReadPublic(tpm, ekHandle, &pub_blob_size, pub_blob, &pub_out, 1355 &pub_name, &qualified_pub_name)) { 1356 printf("ReadPublic succeeded\n"); 1357 } else { 1358 printf("ReadPublic failed\n"); 1359 return false; 1360 } 1361 1362 // Normally, the caller would get the key from the endorsement certificate 1363 EVP_PKEY* tpmKey = EVP_PKEY_new(); 1364 RSA* rsa_tpmKey = RSA_new(); 1365 rsa_tpmKey->n = bin_to_BN((int)pub_out.publicArea.unique.rsa.size, 1366 pub_out.publicArea.unique.rsa.buffer); 1367 uint64_t exp = 0x010001ULL; 1368 byte b_exp[16]; 1369 ChangeEndian64((uint64_t*)&exp, (uint64_t*)b_exp); 1370 rsa_tpmKey->e = bin_to_BN(sizeof(uint64_t), b_exp); 1371 EVP_PKEY_assign_RSA(tpmKey, rsa_tpmKey); 1372 1373 // Encrypt salt 1374 byte padded_secret[1024]; 1375 memset(padded_secret, 0, 1024); 1376 RSA_padding_add_PKCS1_OAEP(padded_secret, 256, 1377 secret.buffer, secret.size, 1378 (byte*)"SECRET", strlen("SECRET")+1); 1379 int n = RSA_public_encrypt(256, padded_secret, salt.secret, 1380 rsa_tpmKey, RSA_NO_PADDING); 1381 salt.size = n; 1382 1383 #if 1 1384 printf("\nEncrypted salt (%d): ", n); 1385 PrintBytes(n, salt.secret); printf("\n"); 1386 #endif 1387 1388 authInfo.protectedHandle_ = nv_handle; 1389 authInfo.protectedAttributes_ = NV_COUNTER | NV_AUTHWRITE | NV_AUTHREAD; 1390 authInfo.protectedSize_ = size_data; 1391 authInfo.hash_alg_ = TPM_ALG_SHA1; 1392 authInfo.tpmSessionAttributes_ = CONTINUESESSION; 1393 extern int SetPasswordData(string& password, int size, byte* buf); 1394 byte tbuf[128]; 1395 int l = SetPasswordData(authString, 128, tbuf); 1396 authInfo.targetAuthValue_.size = l - 2; 1397 memcpy(authInfo.targetAuthValue_.buffer, &tbuf[2], l - 2); 1398 1399 // Start auth session. 1400 if (Tpm2_StartProtectedAuthSession(tpm, ekHandle, TPM_RH_NULL, authInfo, 1401 salt, TPM_SE_HMAC, symmetric, authInfo.hash_alg_, &sessionHandle)) { 1402 printf("Tpm2_StartProtectedAuthSession succeeds handle: %08x\n", 1403 sessionHandle); 1404 } else { 1405 printf("Tpm2_StartProtectedAuthSession fails\n"); 1406 ret = false; 1407 goto done; 1408 } 1409 authInfo.sessionHandle_ = sessionHandle; 1410 1411 #if 1 1412 printf("\nAfterStartProtectedAuthSession\n"); 1413 printf("newNonce: "); 1414 PrintBytes(authInfo.newNonce_.size, authInfo.newNonce_.buffer); printf("\n"); 1415 printf("oldNonce: "); 1416 PrintBytes(authInfo.oldNonce_.size, authInfo.oldNonce_.buffer); printf("\n"); 1417 #endif 1418 1419 // Calculate session key. 1420 if (!CalculateSessionKey(authInfo, secret)) { 1421 printf("Can't calculate HMac session key\n"); 1422 ret = false; 1423 goto done; 1424 } 1425 1426 #if 1 1427 printf("After CalculateSessionKey before IncrementProtected\n"); 1428 printf("newNonce: "); 1429 PrintBytes(authInfo.newNonce_.size, authInfo.newNonce_.buffer); printf("\n"); 1430 printf("oldNonce: "); 1431 PrintBytes(authInfo.oldNonce_.size, authInfo.oldNonce_.buffer); printf("\n"); 1432 #endif 1433 1434 if (Tpm2_IncrementProtectedNv(tpm, nv_handle, authInfo)) { 1435 printf("Tpm2_IncrementProtectedNv %d succeeds\n", nv_handle); 1436 } else { 1437 printf("Tpm2_IncrementProtectedNv fails\n"); 1438 ret = false; 1439 goto done; 1440 } 1441 1442 #if 1 1443 printf("Read Protected\n"); 1444 #endif 1445 1446 size_out = 8; 1447 if (Tpm2_ReadProtectedNv(tpm, nv_handle, authInfo, &size_out, data_out)) { 1448 printf("Tpm2_ReadProtectedNv %d succeeds: ", nv_handle); 1449 PrintBytes(size_out, data_out); 1450 printf("\n"); 1451 } else { 1452 printf("Tpm2_ReadProtectedNv fails\n"); 1453 ret = false; 1454 goto done; 1455 } 1456 1457 done: 1458 if (sessionHandle != 0) { 1459 Tpm2_FlushContext(tpm, sessionHandle); 1460 } 1461 if (ekHandle != 0) { 1462 Tpm2_FlushContext(tpm, ekHandle); 1463 } 1464 return ret; 1465 }