1 // 2 // Copyright (C) 2015 The Android Open Source Project 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 17 #include "trunks/trunks_client_test.h" 18 19 #include <algorithm> 20 #include <map> 21 #include <memory> 22 #include <string> 23 #include <vector> 24 25 #include <base/callback.h> 26 #include <base/logging.h> 27 #include <base/stl_util.h> 28 #include <brillo/bind_lambda.h> 29 #include <crypto/openssl_util.h> 30 #include <crypto/sha2.h> 31 #include <openssl/bio.h> 32 #include <openssl/bn.h> 33 #include <openssl/crypto.h> 34 #include <openssl/err.h> 35 #include <openssl/rsa.h> 36 #include <openssl/ssl.h> 37 38 #include "trunks/authorization_delegate.h" 39 #include "trunks/error_codes.h" 40 #include "trunks/hmac_session.h" 41 #include "trunks/policy_session.h" 42 #include "trunks/scoped_key_handle.h" 43 #include "trunks/tpm_constants.h" 44 #include "trunks/tpm_generated.h" 45 #include "trunks/tpm_state.h" 46 #include "trunks/tpm_utility.h" 47 #include "trunks/trunks_factory_impl.h" 48 49 namespace { 50 51 std::string GetOpenSSLError() { 52 BIO* bio = BIO_new(BIO_s_mem()); 53 ERR_print_errors(bio); 54 char* data = nullptr; 55 int data_len = BIO_get_mem_data(bio, &data); 56 std::string error_string(data, data_len); 57 BIO_free(bio); 58 return error_string; 59 } 60 61 } // namespace 62 63 namespace trunks { 64 65 TrunksClientTest::TrunksClientTest(const TrunksFactory& factory) 66 : factory_(factory) { 67 crypto::EnsureOpenSSLInit(); 68 } 69 70 TrunksClientTest::~TrunksClientTest() {} 71 72 bool TrunksClientTest::RNGTest() { 73 std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility(); 74 std::unique_ptr<HmacSession> session = factory_.GetHmacSession(); 75 if (utility->StartSession(session.get()) != TPM_RC_SUCCESS) { 76 LOG(ERROR) << "Error starting hmac session."; 77 return false; 78 } 79 std::string entropy_data("entropy_data"); 80 std::string random_data; 81 size_t num_bytes = 70; 82 TPM_RC result = utility->StirRandom(entropy_data, session->GetDelegate()); 83 if (result != TPM_RC_SUCCESS) { 84 LOG(ERROR) << "Error stirring TPM RNG: " << GetErrorString(result); 85 return false; 86 } 87 result = 88 utility->GenerateRandom(num_bytes, session->GetDelegate(), &random_data); 89 if (result != TPM_RC_SUCCESS) { 90 LOG(ERROR) << "Error getting random bytes from TPM: " 91 << GetErrorString(result); 92 return false; 93 } 94 if (num_bytes != random_data.size()) { 95 LOG(ERROR) << "Error not enough random bytes received."; 96 return false; 97 } 98 return true; 99 } 100 101 bool TrunksClientTest::SignTest() { 102 std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility(); 103 std::unique_ptr<HmacSession> session = factory_.GetHmacSession(); 104 if (utility->StartSession(session.get()) != TPM_RC_SUCCESS) { 105 LOG(ERROR) << "Error starting hmac session."; 106 return false; 107 } 108 std::string key_authorization("sign"); 109 std::string key_blob; 110 TPM_RC result = utility->CreateRSAKeyPair( 111 TpmUtility::AsymmetricKeyUsage::kSignKey, 2048, 0x10001, 112 key_authorization, "", false, // use_only_policy_authorization 113 kNoCreationPCR, session->GetDelegate(), &key_blob, nullptr); 114 if (result != TPM_RC_SUCCESS) { 115 LOG(ERROR) << "Error creating signing key: " << GetErrorString(result); 116 return false; 117 } 118 TPM_HANDLE signing_key; 119 result = utility->LoadKey(key_blob, session->GetDelegate(), &signing_key); 120 if (result != TPM_RC_SUCCESS) { 121 LOG(ERROR) << "Error loading signing key: " << GetErrorString(result); 122 } 123 ScopedKeyHandle scoped_key(factory_, signing_key); 124 session->SetEntityAuthorizationValue(key_authorization); 125 std::string signature; 126 result = 127 utility->Sign(signing_key, TPM_ALG_NULL, TPM_ALG_NULL, 128 std::string(32, 'a'), session->GetDelegate(), &signature); 129 if (result != TPM_RC_SUCCESS) { 130 LOG(ERROR) << "Error using key to sign: " << GetErrorString(result); 131 return false; 132 } 133 result = utility->Verify(signing_key, TPM_ALG_NULL, TPM_ALG_NULL, 134 std::string(32, 'a'), signature, nullptr); 135 if (result != TPM_RC_SUCCESS) { 136 LOG(ERROR) << "Error using key to verify: " << GetErrorString(result); 137 return false; 138 } 139 return true; 140 } 141 142 bool TrunksClientTest::DecryptTest() { 143 std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility(); 144 std::unique_ptr<HmacSession> session = factory_.GetHmacSession(); 145 if (utility->StartSession(session.get()) != TPM_RC_SUCCESS) { 146 LOG(ERROR) << "Error starting hmac session."; 147 return false; 148 } 149 std::string key_authorization("decrypt"); 150 std::string key_blob; 151 TPM_RC result = utility->CreateRSAKeyPair( 152 TpmUtility::AsymmetricKeyUsage::kDecryptKey, 2048, 0x10001, 153 key_authorization, "", false, // use_only_policy_authorization 154 kNoCreationPCR, session->GetDelegate(), &key_blob, nullptr); 155 if (result != TPM_RC_SUCCESS) { 156 LOG(ERROR) << "Error creating decrypt key: " << GetErrorString(result); 157 return false; 158 } 159 TPM_HANDLE decrypt_key; 160 result = utility->LoadKey(key_blob, session->GetDelegate(), &decrypt_key); 161 if (result != TPM_RC_SUCCESS) { 162 LOG(ERROR) << "Error loading decrypt key: " << GetErrorString(result); 163 } 164 ScopedKeyHandle scoped_key(factory_, decrypt_key); 165 return PerformRSAEncrpytAndDecrpyt(scoped_key.get(), key_authorization, 166 session.get()); 167 } 168 169 bool TrunksClientTest::ImportTest() { 170 std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility(); 171 std::unique_ptr<HmacSession> session = factory_.GetHmacSession(); 172 if (utility->StartSession(session.get()) != TPM_RC_SUCCESS) { 173 LOG(ERROR) << "Error starting hmac session."; 174 return false; 175 } 176 std::string modulus; 177 std::string prime_factor; 178 GenerateRSAKeyPair(&modulus, &prime_factor, nullptr); 179 std::string key_blob; 180 std::string key_authorization("import"); 181 TPM_RC result = utility->ImportRSAKey( 182 TpmUtility::AsymmetricKeyUsage::kDecryptAndSignKey, modulus, 0x10001, 183 prime_factor, key_authorization, session->GetDelegate(), &key_blob); 184 if (result != TPM_RC_SUCCESS) { 185 LOG(ERROR) << "Error importing key into TPM: " << GetErrorString(result); 186 return false; 187 } 188 TPM_HANDLE key_handle; 189 result = utility->LoadKey(key_blob, session->GetDelegate(), &key_handle); 190 if (result != TPM_RC_SUCCESS) { 191 LOG(ERROR) << "Error loading key into TPM: " << GetErrorString(result); 192 return false; 193 } 194 ScopedKeyHandle scoped_key(factory_, key_handle); 195 return PerformRSAEncrpytAndDecrpyt(scoped_key.get(), key_authorization, 196 session.get()); 197 } 198 199 bool TrunksClientTest::AuthChangeTest() { 200 std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility(); 201 std::unique_ptr<HmacSession> session = factory_.GetHmacSession(); 202 if (utility->StartSession(session.get()) != TPM_RC_SUCCESS) { 203 LOG(ERROR) << "Error starting hmac session."; 204 return false; 205 } 206 std::string key_authorization("new_pass"); 207 std::string key_blob; 208 TPM_RC result = utility->CreateRSAKeyPair( 209 TpmUtility::AsymmetricKeyUsage::kDecryptKey, 2048, 0x10001, "old_pass", 210 "", false, // use_only_policy_authorization 211 kNoCreationPCR, session->GetDelegate(), &key_blob, nullptr); 212 if (result != TPM_RC_SUCCESS) { 213 LOG(ERROR) << "Error creating change auth key: " << GetErrorString(result); 214 return false; 215 } 216 TPM_HANDLE key_handle; 217 result = utility->LoadKey(key_blob, session->GetDelegate(), &key_handle); 218 if (result != TPM_RC_SUCCESS) { 219 LOG(ERROR) << "Error loading change auth key: " << GetErrorString(result); 220 } 221 ScopedKeyHandle scoped_key(factory_, key_handle); 222 session->SetEntityAuthorizationValue("old_pass"); 223 result = utility->ChangeKeyAuthorizationData( 224 key_handle, key_authorization, session->GetDelegate(), &key_blob); 225 if (result != TPM_RC_SUCCESS) { 226 LOG(ERROR) << "Error changing auth data: " << GetErrorString(result); 227 return false; 228 } 229 session->SetEntityAuthorizationValue(""); 230 result = utility->LoadKey(key_blob, session->GetDelegate(), &key_handle); 231 if (result != TPM_RC_SUCCESS) { 232 LOG(ERROR) << "Error reloading key: " << GetErrorString(result); 233 return false; 234 } 235 scoped_key.reset(key_handle); 236 return PerformRSAEncrpytAndDecrpyt(scoped_key.get(), key_authorization, 237 session.get()); 238 } 239 240 bool TrunksClientTest::VerifyKeyCreationTest() { 241 std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility(); 242 std::unique_ptr<HmacSession> session = factory_.GetHmacSession(); 243 if (utility->StartSession(session.get()) != TPM_RC_SUCCESS) { 244 LOG(ERROR) << "Error starting hmac session."; 245 return false; 246 } 247 std::string key_blob; 248 std::string creation_blob; 249 session->SetEntityAuthorizationValue(""); 250 TPM_RC result = utility->CreateRSAKeyPair( 251 TpmUtility::AsymmetricKeyUsage::kDecryptKey, 2048, 0x10001, "", "", 252 false, // use_only_policy_authorization 253 kNoCreationPCR, session->GetDelegate(), &key_blob, &creation_blob); 254 if (result != TPM_RC_SUCCESS) { 255 LOG(ERROR) << "Error creating certify key: " << GetErrorString(result); 256 return false; 257 } 258 std::string alternate_key_blob; 259 result = utility->CreateRSAKeyPair( 260 TpmUtility::AsymmetricKeyUsage::kDecryptKey, 2048, 0x10001, "", "", 261 false, // use_only_policy_authorization 262 kNoCreationPCR, session->GetDelegate(), &alternate_key_blob, nullptr); 263 if (result != TPM_RC_SUCCESS) { 264 LOG(ERROR) << "Error creating alternate key: " << GetErrorString(result); 265 return false; 266 } 267 TPM_HANDLE key_handle; 268 result = utility->LoadKey(key_blob, session->GetDelegate(), &key_handle); 269 if (result != TPM_RC_SUCCESS) { 270 LOG(ERROR) << "Error loading certify key: " << GetErrorString(result); 271 return false; 272 } 273 TPM_HANDLE alternate_key_handle; 274 result = utility->LoadKey(alternate_key_blob, session->GetDelegate(), 275 &alternate_key_handle); 276 if (result != TPM_RC_SUCCESS) { 277 LOG(ERROR) << "Error loading alternate key: " << GetErrorString(result); 278 return false; 279 } 280 ScopedKeyHandle certify_key(factory_, key_handle); 281 ScopedKeyHandle alternate_key(factory_, alternate_key_handle); 282 result = utility->CertifyCreation(certify_key.get(), creation_blob); 283 if (result != TPM_RC_SUCCESS) { 284 LOG(ERROR) << "Error certifying key: " << GetErrorString(result); 285 return false; 286 } 287 result = utility->CertifyCreation(alternate_key.get(), creation_blob); 288 if (result == TPM_RC_SUCCESS) { 289 LOG(ERROR) << "Error alternate key certified with wrong creation data."; 290 return false; 291 } 292 return true; 293 } 294 295 bool TrunksClientTest::SealedDataTest() { 296 std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility(); 297 std::unique_ptr<HmacSession> session = factory_.GetHmacSession(); 298 if (utility->StartSession(session.get()) != TPM_RC_SUCCESS) { 299 LOG(ERROR) << "Error starting hmac session."; 300 return false; 301 } 302 int pcr_index = 5; 303 std::string policy_digest; 304 TPM_RC result = 305 utility->GetPolicyDigestForPcrValue(pcr_index, "", &policy_digest); 306 if (result != TPM_RC_SUCCESS) { 307 LOG(ERROR) << "Error getting policy_digest: " << GetErrorString(result); 308 return false; 309 } 310 std::string data_to_seal("seal_data"); 311 std::string sealed_data; 312 result = utility->SealData(data_to_seal, policy_digest, 313 session->GetDelegate(), &sealed_data); 314 if (result != TPM_RC_SUCCESS) { 315 LOG(ERROR) << "Error creating Sealed Object: " << GetErrorString(result); 316 return false; 317 } 318 std::unique_ptr<PolicySession> policy_session = factory_.GetPolicySession(); 319 result = policy_session->StartUnboundSession(false); 320 if (result != TPM_RC_SUCCESS) { 321 LOG(ERROR) << "Error starting policy session: " << GetErrorString(result); 322 return false; 323 } 324 result = policy_session->PolicyPCR(pcr_index, ""); 325 if (result != TPM_RC_SUCCESS) { 326 LOG(ERROR) << "Error restricting policy to pcr value: " 327 << GetErrorString(result); 328 return false; 329 } 330 std::string unsealed_data; 331 result = utility->UnsealData(sealed_data, policy_session->GetDelegate(), 332 &unsealed_data); 333 if (result != TPM_RC_SUCCESS) { 334 LOG(ERROR) << "Error unsealing object: " << GetErrorString(result); 335 return false; 336 } 337 if (data_to_seal != unsealed_data) { 338 LOG(ERROR) << "Error unsealed data from TPM does not match original data."; 339 return false; 340 } 341 result = utility->ExtendPCR(pcr_index, "extend", session->GetDelegate()); 342 if (result != TPM_RC_SUCCESS) { 343 LOG(ERROR) << "Error extending pcr: " << GetErrorString(result); 344 return false; 345 } 346 result = policy_session->PolicyPCR(pcr_index, ""); 347 if (result != TPM_RC_SUCCESS) { 348 LOG(ERROR) << "Error restricting policy to pcr value: " 349 << GetErrorString(result); 350 return false; 351 } 352 result = utility->UnsealData(sealed_data, policy_session->GetDelegate(), 353 &unsealed_data); 354 if (result == TPM_RC_SUCCESS) { 355 LOG(ERROR) << "Error object was unsealed with wrong policy_digest."; 356 return false; 357 } 358 return true; 359 } 360 361 bool TrunksClientTest::PCRTest() { 362 std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility(); 363 std::unique_ptr<HmacSession> session = factory_.GetHmacSession(); 364 if (utility->StartSession(session.get()) != TPM_RC_SUCCESS) { 365 LOG(ERROR) << "Error starting hmac session."; 366 return false; 367 } 368 // We are using PCR 2 because it is currently not used by ChromeOS. 369 uint32_t pcr_index = 2; 370 std::string extend_data("data"); 371 std::string old_data; 372 TPM_RC result = utility->ReadPCR(pcr_index, &old_data); 373 if (result != TPM_RC_SUCCESS) { 374 LOG(ERROR) << "Error reading from PCR: " << GetErrorString(result); 375 return false; 376 } 377 result = utility->ExtendPCR(pcr_index, extend_data, session->GetDelegate()); 378 if (result != TPM_RC_SUCCESS) { 379 LOG(ERROR) << "Error extending PCR value: " << GetErrorString(result); 380 return false; 381 } 382 std::string pcr_data; 383 result = utility->ReadPCR(pcr_index, &pcr_data); 384 if (result != TPM_RC_SUCCESS) { 385 LOG(ERROR) << "Error reading from PCR: " << GetErrorString(result); 386 return false; 387 } 388 std::string hashed_extend_data = crypto::SHA256HashString(extend_data); 389 std::string expected_pcr_data = 390 crypto::SHA256HashString(old_data + hashed_extend_data); 391 if (pcr_data.compare(expected_pcr_data) != 0) { 392 LOG(ERROR) << "PCR data does not match expected value."; 393 return false; 394 } 395 return true; 396 } 397 398 bool TrunksClientTest::PolicyAuthValueTest() { 399 std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility(); 400 std::unique_ptr<PolicySession> trial_session = factory_.GetTrialSession(); 401 TPM_RC result; 402 result = trial_session->StartUnboundSession(true); 403 if (result != TPM_RC_SUCCESS) { 404 LOG(ERROR) << "Error starting policy session: " << GetErrorString(result); 405 return false; 406 } 407 result = trial_session->PolicyAuthValue(); 408 if (result != TPM_RC_SUCCESS) { 409 LOG(ERROR) << "Error restricting policy to auth value knowledge: " 410 << GetErrorString(result); 411 return false; 412 } 413 std::string policy_digest; 414 result = trial_session->GetDigest(&policy_digest); 415 if (result != TPM_RC_SUCCESS) { 416 LOG(ERROR) << "Error getting policy digest: " << GetErrorString(result); 417 return false; 418 } 419 // Now that we have the digest, we can close the trial session and use hmac. 420 trial_session.reset(); 421 422 std::unique_ptr<HmacSession> hmac_session = factory_.GetHmacSession(); 423 result = hmac_session->StartUnboundSession(true); 424 if (result != TPM_RC_SUCCESS) { 425 LOG(ERROR) << "Error starting hmac session: " << GetErrorString(result); 426 return false; 427 } 428 429 std::string key_blob; 430 result = utility->CreateRSAKeyPair( 431 TpmUtility::AsymmetricKeyUsage::kDecryptAndSignKey, 2048, 0x10001, 432 "password", policy_digest, true, // use_only_policy_authorization 433 kNoCreationPCR, hmac_session->GetDelegate(), &key_blob, nullptr); 434 if (result != TPM_RC_SUCCESS) { 435 LOG(ERROR) << "Error creating RSA key: " << GetErrorString(result); 436 return false; 437 } 438 439 TPM_HANDLE key_handle; 440 result = utility->LoadKey(key_blob, hmac_session->GetDelegate(), &key_handle); 441 if (result != TPM_RC_SUCCESS) { 442 LOG(ERROR) << "Error loading RSA key: " << GetErrorString(result); 443 return false; 444 } 445 ScopedKeyHandle scoped_key(factory_, key_handle); 446 447 // Now we can reset the hmac_session. 448 hmac_session.reset(); 449 450 std::unique_ptr<PolicySession> policy_session = factory_.GetPolicySession(); 451 result = policy_session->StartUnboundSession(false); 452 if (result != TPM_RC_SUCCESS) { 453 LOG(ERROR) << "Error starting policy session: " << GetErrorString(result); 454 return false; 455 } 456 result = policy_session->PolicyAuthValue(); 457 if (result != TPM_RC_SUCCESS) { 458 LOG(ERROR) << "Error restricting policy to auth value knowledge: " 459 << GetErrorString(result); 460 return false; 461 } 462 std::string signature; 463 policy_session->SetEntityAuthorizationValue("password"); 464 result = utility->Sign(scoped_key.get(), TPM_ALG_NULL, TPM_ALG_NULL, 465 std::string(32, 0), policy_session->GetDelegate(), 466 &signature); 467 if (result != TPM_RC_SUCCESS) { 468 LOG(ERROR) << "Error signing using RSA key: " << GetErrorString(result); 469 return false; 470 } 471 result = utility->Verify(scoped_key.get(), TPM_ALG_NULL, TPM_ALG_NULL, 472 std::string(32, 0), signature, nullptr); 473 if (result != TPM_RC_SUCCESS) { 474 LOG(ERROR) << "Error verifying using RSA key: " << GetErrorString(result); 475 return false; 476 } 477 std::string ciphertext; 478 result = 479 utility->AsymmetricEncrypt(scoped_key.get(), TPM_ALG_NULL, TPM_ALG_NULL, 480 "plaintext", nullptr, &ciphertext); 481 if (result != TPM_RC_SUCCESS) { 482 LOG(ERROR) << "Error encrypting using RSA key: " << GetErrorString(result); 483 return false; 484 } 485 result = policy_session->PolicyAuthValue(); 486 if (result != TPM_RC_SUCCESS) { 487 LOG(ERROR) << "Error restricting policy to auth value knowledge: " 488 << GetErrorString(result); 489 return false; 490 } 491 std::string plaintext; 492 policy_session->SetEntityAuthorizationValue("password"); 493 result = utility->AsymmetricDecrypt( 494 scoped_key.get(), TPM_ALG_NULL, TPM_ALG_NULL, ciphertext, 495 policy_session->GetDelegate(), &plaintext); 496 if (result != TPM_RC_SUCCESS) { 497 LOG(ERROR) << "Error encrypting using RSA key: " << GetErrorString(result); 498 return false; 499 } 500 if (plaintext.compare("plaintext") != 0) { 501 LOG(ERROR) << "Plaintext changed after encrypt + decrypt."; 502 return false; 503 } 504 return true; 505 } 506 507 bool TrunksClientTest::PolicyAndTest() { 508 std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility(); 509 std::unique_ptr<PolicySession> trial_session = factory_.GetTrialSession(); 510 TPM_RC result; 511 result = trial_session->StartUnboundSession(true); 512 if (result != TPM_RC_SUCCESS) { 513 LOG(ERROR) << "Error starting policy session: " << GetErrorString(result); 514 return false; 515 } 516 result = trial_session->PolicyCommandCode(TPM_CC_Sign); 517 if (result != TPM_RC_SUCCESS) { 518 LOG(ERROR) << "Error restricting policy: " << GetErrorString(result); 519 return false; 520 } 521 uint32_t pcr_index = 2; 522 std::string pcr_value; 523 result = utility->ReadPCR(pcr_index, &pcr_value); 524 if (result != TPM_RC_SUCCESS) { 525 LOG(ERROR) << "Error reading pcr: " << GetErrorString(result); 526 return false; 527 } 528 std::string pcr_extend_data("extend"); 529 std::string next_pcr_value; 530 std::string hashed_extend_data = crypto::SHA256HashString(pcr_extend_data); 531 next_pcr_value = crypto::SHA256HashString(pcr_value + hashed_extend_data); 532 533 result = trial_session->PolicyPCR(pcr_index, next_pcr_value); 534 if (result != TPM_RC_SUCCESS) { 535 LOG(ERROR) << "Error restricting policy: " << GetErrorString(result); 536 return false; 537 } 538 std::string policy_digest; 539 result = trial_session->GetDigest(&policy_digest); 540 if (result != TPM_RC_SUCCESS) { 541 LOG(ERROR) << "Error getting policy digest: " << GetErrorString(result); 542 return false; 543 } 544 // Now that we have the digest, we can close the trial session and use hmac. 545 trial_session.reset(); 546 547 std::unique_ptr<HmacSession> hmac_session = factory_.GetHmacSession(); 548 result = hmac_session->StartUnboundSession(true); 549 if (result != TPM_RC_SUCCESS) { 550 LOG(ERROR) << "Error starting hmac session: " << GetErrorString(result); 551 return false; 552 } 553 std::string key_authorization("password"); 554 std::string key_blob; 555 // This key is created with a policy that dictates it can only be used 556 // when pcr 2 remains unchanged, and when the command is TPM2_Sign. 557 result = utility->CreateRSAKeyPair( 558 TpmUtility::AsymmetricKeyUsage::kDecryptAndSignKey, 2048, 0x10001, 559 key_authorization, policy_digest, true, // use_only_policy_authorization 560 kNoCreationPCR, hmac_session->GetDelegate(), &key_blob, nullptr); 561 if (result != TPM_RC_SUCCESS) { 562 LOG(ERROR) << "Error creating RSA key: " << GetErrorString(result); 563 return false; 564 } 565 TPM_HANDLE key_handle; 566 result = utility->LoadKey(key_blob, hmac_session->GetDelegate(), &key_handle); 567 if (result != TPM_RC_SUCCESS) { 568 LOG(ERROR) << "Error loading RSA key: " << GetErrorString(result); 569 return false; 570 } 571 ScopedKeyHandle scoped_key(factory_, key_handle); 572 573 // Now we can reset the hmac_session. 574 hmac_session.reset(); 575 576 std::unique_ptr<PolicySession> policy_session = factory_.GetPolicySession(); 577 result = policy_session->StartUnboundSession(false); 578 if (result != TPM_RC_SUCCESS) { 579 LOG(ERROR) << "Error starting policy session: " << GetErrorString(result); 580 return false; 581 } 582 result = policy_session->PolicyCommandCode(TPM_CC_Sign); 583 if (result != TPM_RC_SUCCESS) { 584 LOG(ERROR) << "Error restricting policy: " << GetErrorString(result); 585 return false; 586 } 587 result = policy_session->PolicyPCR(pcr_index, ""); 588 if (result != TPM_RC_SUCCESS) { 589 LOG(ERROR) << "Error restricting policy: " << GetErrorString(result); 590 return false; 591 } 592 std::string signature; 593 policy_session->SetEntityAuthorizationValue(key_authorization); 594 // Signing with this key when pcr 2 is unchanged fails. 595 result = utility->Sign(scoped_key.get(), TPM_ALG_NULL, TPM_ALG_NULL, 596 std::string(32, 'a'), policy_session->GetDelegate(), 597 &signature); 598 if (GetFormatOneError(result) != TPM_RC_POLICY_FAIL) { 599 LOG(ERROR) << "Error using key to sign: " << GetErrorString(result); 600 return false; 601 } 602 std::unique_ptr<AuthorizationDelegate> delegate = 603 factory_.GetPasswordAuthorization(""); 604 result = utility->ExtendPCR(pcr_index, pcr_extend_data, delegate.get()); 605 if (result != TPM_RC_SUCCESS) { 606 LOG(ERROR) << "Error extending pcr: " << GetErrorString(result); 607 return false; 608 } 609 // we have to restart the session because we changed the pcr values. 610 result = policy_session->StartUnboundSession(false); 611 if (result != TPM_RC_SUCCESS) { 612 LOG(ERROR) << "Error starting policy session: " << GetErrorString(result); 613 return false; 614 } 615 result = policy_session->PolicyCommandCode(TPM_CC_Sign); 616 if (result != TPM_RC_SUCCESS) { 617 LOG(ERROR) << "Error restricting policy: " << GetErrorString(result); 618 return false; 619 } 620 result = policy_session->PolicyPCR(pcr_index, ""); 621 if (result != TPM_RC_SUCCESS) { 622 LOG(ERROR) << "Error restricting policy: " << GetErrorString(result); 623 return false; 624 } 625 policy_session->SetEntityAuthorizationValue(key_authorization); 626 // Signing with this key when pcr 2 is changed succeeds. 627 result = utility->Sign(scoped_key.get(), TPM_ALG_NULL, TPM_ALG_NULL, 628 std::string(32, 'a'), policy_session->GetDelegate(), 629 &signature); 630 if (result != TPM_RC_SUCCESS) { 631 LOG(ERROR) << "Error using key to sign: " << GetErrorString(result); 632 return false; 633 } 634 result = utility->Verify(scoped_key.get(), TPM_ALG_NULL, TPM_ALG_NULL, 635 std::string(32, 'a'), signature, nullptr); 636 if (result != TPM_RC_SUCCESS) { 637 LOG(ERROR) << "Error using key to verify: " << GetErrorString(result); 638 return false; 639 } 640 std::string ciphertext; 641 result = utility->AsymmetricEncrypt(key_handle, TPM_ALG_NULL, TPM_ALG_NULL, 642 "plaintext", nullptr, &ciphertext); 643 if (result != TPM_RC_SUCCESS) { 644 LOG(ERROR) << "Error using key to encrypt: " << GetErrorString(result); 645 return false; 646 } 647 result = policy_session->PolicyCommandCode(TPM_CC_Sign); 648 if (result != TPM_RC_SUCCESS) { 649 LOG(ERROR) << "Error restricting policy: " << GetErrorString(result); 650 return false; 651 } 652 result = policy_session->PolicyPCR(pcr_index, ""); 653 if (result != TPM_RC_SUCCESS) { 654 LOG(ERROR) << "Error restricting policy: " << GetErrorString(result); 655 return false; 656 } 657 std::string plaintext; 658 policy_session->SetEntityAuthorizationValue(key_authorization); 659 // This call is not authorized with the policy, because its command code 660 // is not TPM_CC_SIGN. It should fail with TPM_RC_POLICY_CC. 661 result = utility->AsymmetricDecrypt(key_handle, TPM_ALG_NULL, TPM_ALG_NULL, 662 ciphertext, policy_session->GetDelegate(), 663 &plaintext); 664 if (GetFormatOneError(result) != TPM_RC_POLICY_CC) { 665 LOG(ERROR) << "Error: " << GetErrorString(result); 666 return false; 667 } 668 return true; 669 } 670 671 bool TrunksClientTest::PolicyOrTest() { 672 std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility(); 673 std::unique_ptr<PolicySession> trial_session = factory_.GetTrialSession(); 674 TPM_RC result; 675 // Specify a policy that asserts either TPM_CC_RSA_Encrypt or 676 // TPM_CC_RSA_Decrypt. A key created under this policy can only be used 677 // to encrypt or decrypt. 678 result = trial_session->StartUnboundSession(true); 679 if (result != TPM_RC_SUCCESS) { 680 LOG(ERROR) << "Error starting policy session: " << GetErrorString(result); 681 return false; 682 } 683 result = trial_session->PolicyCommandCode(TPM_CC_Sign); 684 if (result != TPM_RC_SUCCESS) { 685 LOG(ERROR) << "Error restricting policy: " << GetErrorString(result); 686 return false; 687 } 688 std::string sign_digest; 689 result = trial_session->GetDigest(&sign_digest); 690 if (result != TPM_RC_SUCCESS) { 691 LOG(ERROR) << "Error getting policy digest: " << GetErrorString(result); 692 return false; 693 } 694 result = trial_session->StartUnboundSession(true); 695 if (result != TPM_RC_SUCCESS) { 696 LOG(ERROR) << "Error starting policy session: " << GetErrorString(result); 697 return false; 698 } 699 result = trial_session->PolicyCommandCode(TPM_CC_RSA_Decrypt); 700 if (result != TPM_RC_SUCCESS) { 701 LOG(ERROR) << "Error restricting policy: " << GetErrorString(result); 702 return false; 703 } 704 std::string decrypt_digest; 705 result = trial_session->GetDigest(&decrypt_digest); 706 if (result != TPM_RC_SUCCESS) { 707 LOG(ERROR) << "Error getting policy digest: " << GetErrorString(result); 708 return false; 709 } 710 std::vector<std::string> digests; 711 digests.push_back(sign_digest); 712 digests.push_back(decrypt_digest); 713 result = trial_session->PolicyOR(digests); 714 if (result != TPM_RC_SUCCESS) { 715 LOG(ERROR) << "Error restricting policy: " << GetErrorString(result); 716 return false; 717 } 718 std::string policy_digest; 719 result = trial_session->GetDigest(&policy_digest); 720 if (result != TPM_RC_SUCCESS) { 721 LOG(ERROR) << "Error getting policy digest: " << GetErrorString(result); 722 return false; 723 } 724 // Now that we have the digest, we can close the trial session and use hmac. 725 trial_session.reset(); 726 727 std::unique_ptr<HmacSession> hmac_session = factory_.GetHmacSession(); 728 result = hmac_session->StartUnboundSession(true); 729 if (result != TPM_RC_SUCCESS) { 730 LOG(ERROR) << "Error starting hmac session: " << GetErrorString(result); 731 return false; 732 } 733 std::string key_authorization("password"); 734 std::string key_blob; 735 // This key is created with a policy that specifies that it can only be used 736 // for encrypt and decrypt operations. 737 result = utility->CreateRSAKeyPair( 738 TpmUtility::AsymmetricKeyUsage::kDecryptAndSignKey, 2048, 0x10001, 739 key_authorization, policy_digest, true, // use_only_policy_authorization 740 kNoCreationPCR, hmac_session->GetDelegate(), &key_blob, nullptr); 741 if (result != TPM_RC_SUCCESS) { 742 LOG(ERROR) << "Error creating RSA key: " << GetErrorString(result); 743 return false; 744 } 745 TPM_HANDLE key_handle; 746 result = utility->LoadKey(key_blob, hmac_session->GetDelegate(), &key_handle); 747 if (result != TPM_RC_SUCCESS) { 748 LOG(ERROR) << "Error loading RSA key: " << GetErrorString(result); 749 return false; 750 } 751 ScopedKeyHandle scoped_key(factory_, key_handle); 752 753 // Now we can reset the hmac_session. 754 hmac_session.reset(); 755 756 std::unique_ptr<PolicySession> policy_session = factory_.GetPolicySession(); 757 result = policy_session->StartUnboundSession(false); 758 if (result != TPM_RC_SUCCESS) { 759 LOG(ERROR) << "Error starting policy session: " << GetErrorString(result); 760 return false; 761 } 762 std::string ciphertext; 763 result = utility->AsymmetricEncrypt(key_handle, TPM_ALG_NULL, TPM_ALG_NULL, 764 "plaintext", nullptr, &ciphertext); 765 if (result != TPM_RC_SUCCESS) { 766 LOG(ERROR) << "Error using key to encrypt: " << GetErrorString(result); 767 return false; 768 } 769 result = policy_session->PolicyCommandCode(TPM_CC_RSA_Decrypt); 770 if (result != TPM_RC_SUCCESS) { 771 LOG(ERROR) << "Error restricting policy: " << GetErrorString(result); 772 return false; 773 } 774 result = policy_session->PolicyOR(digests); 775 if (result != TPM_RC_SUCCESS) { 776 LOG(ERROR) << "Error restricting policy: " << GetErrorString(result); 777 return false; 778 } 779 std::string plaintext; 780 policy_session->SetEntityAuthorizationValue(key_authorization); 781 // We can freely use the key for decryption. 782 result = utility->AsymmetricDecrypt(key_handle, TPM_ALG_NULL, TPM_ALG_NULL, 783 ciphertext, policy_session->GetDelegate(), 784 &plaintext); 785 if (result != TPM_RC_SUCCESS) { 786 LOG(ERROR) << "Error using key to decrypt: " << GetErrorString(result); 787 return false; 788 } 789 if (plaintext.compare("plaintext") != 0) { 790 LOG(ERROR) << "Plaintext changed after encrypt + decrypt."; 791 return false; 792 } 793 result = policy_session->PolicyCommandCode(TPM_CC_Sign); 794 if (result != TPM_RC_SUCCESS) { 795 LOG(ERROR) << "Error restricting policy: " << GetErrorString(result); 796 return false; 797 } 798 result = policy_session->PolicyOR(digests); 799 if (result != TPM_RC_SUCCESS) { 800 LOG(ERROR) << "Error restricting policy: " << GetErrorString(result); 801 return false; 802 } 803 std::string signature; 804 policy_session->SetEntityAuthorizationValue(key_authorization); 805 // However signing with a key only authorized for encrypt/decrypt should 806 // fail with TPM_RC_POLICY_CC. 807 result = utility->Sign(scoped_key.get(), TPM_ALG_NULL, TPM_ALG_NULL, 808 std::string(32, 'a'), policy_session->GetDelegate(), 809 &signature); 810 if (result != TPM_RC_SUCCESS) { 811 LOG(ERROR) << "Error using key to sign: " << GetErrorString(result); 812 return false; 813 } 814 return true; 815 } 816 817 bool TrunksClientTest::NvramTest(const std::string& owner_password) { 818 std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility(); 819 std::unique_ptr<HmacSession> session = factory_.GetHmacSession(); 820 TPM_RC result = session->StartUnboundSession(true /* enable encryption */); 821 if (result != TPM_RC_SUCCESS) { 822 LOG(ERROR) << "Error starting hmac session: " << GetErrorString(result); 823 return false; 824 } 825 uint32_t index = 1; 826 session->SetEntityAuthorizationValue(owner_password); 827 std::string nv_data("nv_data"); 828 TPMA_NV attributes = TPMA_NV_OWNERWRITE | TPMA_NV_AUTHREAD | 829 TPMA_NV_WRITE_STCLEAR | TPMA_NV_READ_STCLEAR; 830 result = utility->DefineNVSpace(index, nv_data.size(), attributes, "", "", 831 session->GetDelegate()); 832 if (result != TPM_RC_SUCCESS) { 833 LOG(ERROR) << "Error defining nvram: " << GetErrorString(result); 834 return false; 835 } 836 // Setup auto-cleanup of the NVRAM space. 837 auto cleanup = [](HmacSession* session, const std::string& owner_password, 838 TpmUtility* utility, uint32_t index) { 839 session->SetEntityAuthorizationValue(owner_password); 840 TPM_RC result = utility->DestroyNVSpace(index, session->GetDelegate()); 841 if (result != TPM_RC_SUCCESS) { 842 LOG(ERROR) << "Error destroying nvram: " << GetErrorString(result); 843 } 844 }; 845 class Scoper { 846 public: 847 explicit Scoper(const base::Closure& callback) : callback_(callback) {} 848 ~Scoper() { 849 if (!cancel_) 850 callback_.Run(); 851 } 852 void Cancel() { cancel_ = true; } 853 854 private: 855 base::Closure callback_; 856 bool cancel_ = false; 857 } scoper(base::Bind(cleanup, base::Unretained(session.get()), owner_password, 858 base::Unretained(utility.get()), index)); 859 860 session->SetEntityAuthorizationValue(owner_password); 861 result = utility->WriteNVSpace(index, 0, nv_data, true /*owner*/, 862 false /*extend*/, session->GetDelegate()); 863 if (result != TPM_RC_SUCCESS) { 864 LOG(ERROR) << "Error writing nvram: " << GetErrorString(result); 865 return false; 866 } 867 std::string new_nvdata; 868 session->SetEntityAuthorizationValue(""); 869 result = utility->ReadNVSpace(index, 0, nv_data.size(), false /*owner*/, 870 &new_nvdata, session->GetDelegate()); 871 if (result != TPM_RC_SUCCESS) { 872 LOG(ERROR) << "Error reading nvram: " << GetErrorString(result); 873 return false; 874 } 875 if (nv_data.compare(new_nvdata) != 0) { 876 LOG(ERROR) << "NV space had different data than was written."; 877 return false; 878 } 879 session->SetEntityAuthorizationValue(owner_password); 880 result = utility->LockNVSpace(index, false /*lock_read*/, true /*lock_write*/, 881 false /*owner*/, session->GetDelegate()); 882 if (result != TPM_RC_SUCCESS) { 883 LOG(ERROR) << "Error locking nvram write: " << GetErrorString(result); 884 return false; 885 } 886 session->SetEntityAuthorizationValue(""); 887 result = utility->ReadNVSpace(index, 0, nv_data.size(), false /*owner*/, 888 &new_nvdata, session->GetDelegate()); 889 if (result != TPM_RC_SUCCESS) { 890 LOG(ERROR) << "Error reading nvram: " << GetErrorString(result); 891 return false; 892 } 893 if (nv_data.compare(new_nvdata) != 0) { 894 LOG(ERROR) << "NV space had different data than was written."; 895 return false; 896 } 897 session->SetEntityAuthorizationValue(owner_password); 898 result = utility->WriteNVSpace(index, 0, nv_data, true /*owner*/, 899 false /*extend*/, session->GetDelegate()); 900 if (result == TPM_RC_SUCCESS) { 901 LOG(ERROR) << "Wrote nvram after locking!"; 902 return false; 903 } 904 result = utility->LockNVSpace(index, true /*lock_read*/, false /*lock_write*/, 905 true /*owner*/, session->GetDelegate()); 906 if (result != TPM_RC_SUCCESS) { 907 LOG(ERROR) << "Error locking nvram read: " << GetErrorString(result); 908 return false; 909 } 910 result = utility->ReadNVSpace(index, 0, nv_data.size(), false /*owner*/, 911 &new_nvdata, session->GetDelegate()); 912 if (result == TPM_RC_SUCCESS) { 913 LOG(ERROR) << "Read nvram after locking!"; 914 return false; 915 } 916 return true; 917 } 918 919 bool TrunksClientTest::ManyKeysTest() { 920 const size_t kNumKeys = 20; 921 std::vector<std::unique_ptr<ScopedKeyHandle>> key_handles; 922 std::map<TPM_HANDLE, std::string> public_key_map; 923 for (size_t i = 0; i < kNumKeys; ++i) { 924 std::unique_ptr<ScopedKeyHandle> key_handle(new ScopedKeyHandle(factory_)); 925 std::string public_key; 926 if (!LoadSigningKey(key_handle.get(), &public_key)) { 927 LOG(ERROR) << "Error loading key " << i << " into TPM."; 928 } 929 public_key_map[key_handle->get()] = public_key; 930 key_handles.push_back(std::move(key_handle)); 931 } 932 CHECK_EQ(key_handles.size(), kNumKeys); 933 CHECK_EQ(public_key_map.size(), kNumKeys); 934 std::unique_ptr<AuthorizationDelegate> delegate = 935 factory_.GetPasswordAuthorization(""); 936 for (size_t i = 0; i < kNumKeys; ++i) { 937 const ScopedKeyHandle& key_handle = *key_handles[i]; 938 const std::string& public_key = public_key_map[key_handle.get()]; 939 if (!SignAndVerify(key_handle, public_key, delegate.get())) { 940 LOG(ERROR) << "Error signing with key " << i; 941 } 942 } 943 std::random_shuffle(key_handles.begin(), key_handles.end()); 944 for (size_t i = 0; i < kNumKeys; ++i) { 945 const ScopedKeyHandle& key_handle = *key_handles[i]; 946 const std::string& public_key = public_key_map[key_handle.get()]; 947 if (!SignAndVerify(key_handle, public_key, delegate.get())) { 948 LOG(ERROR) << "Error signing with shuffled key " << i; 949 } 950 } 951 return true; 952 } 953 954 bool TrunksClientTest::ManySessionsTest() { 955 const size_t kNumSessions = 20; 956 std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility(); 957 std::vector<std::unique_ptr<HmacSession>> sessions; 958 for (size_t i = 0; i < kNumSessions; ++i) { 959 std::unique_ptr<HmacSession> session(factory_.GetHmacSession().release()); 960 TPM_RC result = session->StartUnboundSession(true /* enable encryption */); 961 if (result != TPM_RC_SUCCESS) { 962 LOG(ERROR) << "Error starting hmac session " << i << ": " 963 << GetErrorString(result); 964 return false; 965 } 966 sessions.push_back(std::move(session)); 967 } 968 CHECK_EQ(sessions.size(), kNumSessions); 969 ScopedKeyHandle key_handle(factory_); 970 std::string public_key; 971 if (!LoadSigningKey(&key_handle, &public_key)) { 972 return false; 973 } 974 for (size_t i = 0; i < kNumSessions; ++i) { 975 if (!SignAndVerify(key_handle, public_key, sessions[i]->GetDelegate())) { 976 LOG(ERROR) << "Error signing with hmac session " << i; 977 } 978 } 979 std::random_shuffle(sessions.begin(), sessions.end()); 980 for (size_t i = 0; i < kNumSessions; ++i) { 981 if (!SignAndVerify(key_handle, public_key, sessions[i]->GetDelegate())) { 982 LOG(ERROR) << "Error signing with shuffled hmac session " << i; 983 } 984 } 985 return true; 986 } 987 988 bool TrunksClientTest::PerformRSAEncrpytAndDecrpyt( 989 TPM_HANDLE key_handle, 990 const std::string& key_authorization, 991 HmacSession* session) { 992 std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility(); 993 std::string ciphertext; 994 session->SetEntityAuthorizationValue(""); 995 TPM_RC result = utility->AsymmetricEncrypt( 996 key_handle, TPM_ALG_NULL, TPM_ALG_NULL, "plaintext", 997 session->GetDelegate(), &ciphertext); 998 if (result != TPM_RC_SUCCESS) { 999 LOG(ERROR) << "Error using key to encrypt: " << GetErrorString(result); 1000 return false; 1001 } 1002 std::string plaintext; 1003 session->SetEntityAuthorizationValue(key_authorization); 1004 result = utility->AsymmetricDecrypt(key_handle, TPM_ALG_NULL, TPM_ALG_NULL, 1005 ciphertext, session->GetDelegate(), 1006 &plaintext); 1007 if (result != TPM_RC_SUCCESS) { 1008 LOG(ERROR) << "Error using key to decrypt: " << GetErrorString(result); 1009 return false; 1010 } 1011 if (plaintext.compare("plaintext") != 0) { 1012 LOG(ERROR) << "Plaintext changed after encrypt + decrypt."; 1013 return false; 1014 } 1015 return true; 1016 } 1017 1018 void TrunksClientTest::GenerateRSAKeyPair(std::string* modulus, 1019 std::string* prime_factor, 1020 std::string* public_key) { 1021 #if defined(OPENSSL_IS_BORINGSSL) 1022 bssl::UniquePtr<RSA> rsa(RSA_new()); 1023 bssl::UniquePtr<BIGNUM> exponent(BN_new()); 1024 CHECK(BN_set_word(exponent.get(), RSA_F4)); 1025 CHECK(RSA_generate_key_ex(rsa.get(), 2048, exponent.get(), nullptr)) 1026 << "Failed to generate RSA key: " << GetOpenSSLError(); 1027 #else 1028 bssl::UniquePtr<RSA> rsa(RSA_generate_key(2048, 0x10001, nullptr, nullptr)); 1029 CHECK(rsa.get()); 1030 #endif 1031 modulus->resize(BN_num_bytes(rsa.get()->n), 0); 1032 BN_bn2bin(rsa.get()->n, 1033 reinterpret_cast<unsigned char*>(base::string_as_array(modulus))); 1034 prime_factor->resize(BN_num_bytes(rsa.get()->p), 0); 1035 BN_bn2bin(rsa.get()->p, reinterpret_cast<unsigned char*>( 1036 base::string_as_array(prime_factor))); 1037 if (public_key) { 1038 unsigned char* buffer = NULL; 1039 int length = i2d_RSAPublicKey(rsa.get(), &buffer); 1040 CHECK_GT(length, 0); 1041 public_key->assign(reinterpret_cast<char*>(buffer), length); 1042 OPENSSL_free(buffer); 1043 } 1044 } 1045 1046 bool TrunksClientTest::VerifyRSASignature(const std::string& public_key, 1047 const std::string& data, 1048 const std::string& signature) { 1049 auto asn1_ptr = reinterpret_cast<const unsigned char*>(public_key.data()); 1050 bssl::UniquePtr<RSA> rsa( 1051 d2i_RSAPublicKey(nullptr, &asn1_ptr, public_key.size())); 1052 CHECK(rsa.get()); 1053 std::string digest = crypto::SHA256HashString(data); 1054 auto digest_buffer = reinterpret_cast<const unsigned char*>(digest.data()); 1055 std::string mutable_signature(signature); 1056 unsigned char* signature_buffer = reinterpret_cast<unsigned char*>( 1057 base::string_as_array(&mutable_signature)); 1058 return (RSA_verify(NID_sha256, digest_buffer, digest.size(), signature_buffer, 1059 signature.size(), rsa.get()) == 1); 1060 } 1061 1062 bool TrunksClientTest::LoadSigningKey(ScopedKeyHandle* key_handle, 1063 std::string* public_key) { 1064 std::string modulus; 1065 std::string prime_factor; 1066 GenerateRSAKeyPair(&modulus, &prime_factor, public_key); 1067 std::string key_blob; 1068 std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility(); 1069 TPM_RC result = utility->ImportRSAKey( 1070 TpmUtility::AsymmetricKeyUsage::kSignKey, modulus, 0x10001, prime_factor, 1071 "", // password 1072 factory_.GetPasswordAuthorization("").get(), &key_blob); 1073 if (result != TPM_RC_SUCCESS) { 1074 LOG(ERROR) << "ImportRSAKey: " << GetErrorString(result); 1075 return false; 1076 } 1077 TPM_HANDLE raw_key_handle; 1078 result = utility->LoadKey( 1079 key_blob, factory_.GetPasswordAuthorization("").get(), &raw_key_handle); 1080 if (result != TPM_RC_SUCCESS) { 1081 LOG(ERROR) << "LoadKey: " << GetErrorString(result); 1082 return false; 1083 } 1084 key_handle->reset(raw_key_handle); 1085 return true; 1086 } 1087 1088 bool TrunksClientTest::SignAndVerify(const ScopedKeyHandle& key_handle, 1089 const std::string& public_key, 1090 AuthorizationDelegate* delegate) { 1091 std::string signature; 1092 std::string data_to_sign("sign_this"); 1093 std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility(); 1094 TPM_RC result = 1095 utility->Sign(key_handle.get(), TPM_ALG_RSASSA, TPM_ALG_SHA256, 1096 data_to_sign, delegate, &signature); 1097 if (result != TPM_RC_SUCCESS) { 1098 LOG(ERROR) << "Sign: " << GetErrorString(result); 1099 return false; 1100 } 1101 if (!VerifyRSASignature(public_key, data_to_sign, signature)) { 1102 LOG(ERROR) << "Signature verification failed: " << GetOpenSSLError(); 1103 return false; 1104 } 1105 return true; 1106 } 1107 1108 } // namespace trunks 1109