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