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