Home | History | Annotate | Download | only in trunks
      1 //
      2 // Copyright (C) 2014 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/tpm_utility_impl.h"
     18 
     19 #include <base/logging.h>
     20 #include <base/memory/scoped_ptr.h>
     21 #include <base/sha1.h>
     22 #include <base/stl_util.h>
     23 #include <crypto/openssl_util.h>
     24 #include <crypto/secure_hash.h>
     25 #include <crypto/sha2.h>
     26 #include <openssl/aes.h>
     27 #include <openssl/rand.h>
     28 
     29 #include "trunks/authorization_delegate.h"
     30 #include "trunks/blob_parser.h"
     31 #include "trunks/error_codes.h"
     32 #include "trunks/hmac_authorization_delegate.h"
     33 #include "trunks/hmac_session.h"
     34 #include "trunks/policy_session.h"
     35 #include "trunks/scoped_key_handle.h"
     36 #include "trunks/tpm_constants.h"
     37 #include "trunks/tpm_state.h"
     38 #include "trunks/trunks_factory.h"
     39 
     40 namespace {
     41 
     42 const char kPlatformPassword[] = "cros-platform";
     43 const char kWellKnownPassword[] = "cros-password";
     44 const size_t kMaxPasswordLength = 32;
     45 // The below maximum is defined in TPM 2.0 Library Spec Part 2 Section 13.1
     46 const uint32_t kMaxNVSpaceIndex = (1<<24) - 1;
     47 
     48 // Returns a serialized representation of the unmodified handle. This is useful
     49 // for predefined handle values, like TPM_RH_OWNER. For details on what types of
     50 // handles use this name formula see Table 3 in the TPM 2.0 Library Spec Part 1
     51 // (Section 16 - Names).
     52 std::string NameFromHandle(trunks::TPM_HANDLE handle) {
     53   std::string name;
     54   trunks::Serialize_TPM_HANDLE(handle, &name);
     55   return name;
     56 }
     57 
     58 std::string HashString(const std::string& plaintext,
     59                        trunks::TPM_ALG_ID hash_alg) {
     60   switch (hash_alg) {
     61     case trunks::TPM_ALG_SHA1:
     62       return base::SHA1HashString(plaintext);
     63     case trunks::TPM_ALG_SHA256:
     64       return crypto::SHA256HashString(plaintext);
     65   }
     66   NOTREACHED();
     67   return std::string();
     68 }
     69 
     70 }  // namespace
     71 
     72 namespace trunks {
     73 
     74 TpmUtilityImpl::TpmUtilityImpl(const TrunksFactory& factory)
     75     : factory_(factory) {
     76   crypto::EnsureOpenSSLInit();
     77 }
     78 
     79 TpmUtilityImpl::~TpmUtilityImpl() {
     80 }
     81 
     82 TPM_RC TpmUtilityImpl::Startup() {
     83   TPM_RC result = TPM_RC_SUCCESS;
     84   Tpm* tpm = factory_.GetTpm();
     85   result = tpm->StartupSync(TPM_SU_CLEAR, nullptr);
     86   // Ignore TPM_RC_INITIALIZE, that means it was already started.
     87   if (result && result != TPM_RC_INITIALIZE) {
     88     LOG(ERROR) << __func__ << ": " << GetErrorString(result);
     89     return result;
     90   }
     91   result = tpm->SelfTestSync(YES /* Full test. */, nullptr);
     92   if (result) {
     93     LOG(ERROR) << __func__ << ": " << GetErrorString(result);
     94     return result;
     95   }
     96   return TPM_RC_SUCCESS;
     97 }
     98 
     99 TPM_RC TpmUtilityImpl::Clear() {
    100   TPM_RC result = TPM_RC_SUCCESS;
    101   scoped_ptr<AuthorizationDelegate> password_delegate(
    102       factory_.GetPasswordAuthorization(""));
    103   result = factory_.GetTpm()->ClearSync(TPM_RH_PLATFORM,
    104                                         NameFromHandle(TPM_RH_PLATFORM),
    105                                         password_delegate.get());
    106   // If there was an error in the initialization, platform auth is in a bad
    107   // state.
    108   if (result == TPM_RC_AUTH_MISSING) {
    109     scoped_ptr<AuthorizationDelegate> authorization(
    110         factory_.GetPasswordAuthorization(kPlatformPassword));
    111     result = factory_.GetTpm()->ClearSync(TPM_RH_PLATFORM,
    112                                           NameFromHandle(TPM_RH_PLATFORM),
    113                                           authorization.get());
    114   }
    115   if (GetFormatOneError(result) == TPM_RC_BAD_AUTH) {
    116     LOG(INFO) << "Clear failed because of BAD_AUTH. This probably means "
    117               << "that the TPM was already initialized.";
    118     return result;
    119   }
    120   if (result) {
    121     LOG(ERROR) << "Failed to clear the TPM: " << GetErrorString(result);
    122   }
    123   return result;
    124 }
    125 
    126 void TpmUtilityImpl::Shutdown() {
    127   TPM_RC return_code = factory_.GetTpm()->ShutdownSync(TPM_SU_CLEAR, nullptr);
    128   if (return_code && return_code != TPM_RC_INITIALIZE) {
    129     // This should not happen, but if it does, there is nothing we can do.
    130     LOG(ERROR) << "Error shutting down: " << GetErrorString(return_code);
    131   }
    132 }
    133 
    134 TPM_RC TpmUtilityImpl::InitializeTpm() {
    135   TPM_RC result = TPM_RC_SUCCESS;
    136   scoped_ptr<TpmState> tpm_state(factory_.GetTpmState());
    137   result = tpm_state->Initialize();
    138   if (result) {
    139     LOG(ERROR) << __func__ << ": " << GetErrorString(result);
    140     return result;
    141   }
    142   // Warn about various unexpected conditions.
    143   if (!tpm_state->WasShutdownOrderly()) {
    144     LOG(WARNING) << "WARNING: The last TPM shutdown was not orderly.";
    145   }
    146   if (tpm_state->IsInLockout()) {
    147     LOG(WARNING) << "WARNING: The TPM is currently in lockout.";
    148   }
    149 
    150   // We expect the firmware has already locked down the platform hierarchy. If
    151   // it hasn't, do it now.
    152   if (tpm_state->IsPlatformHierarchyEnabled()) {
    153     scoped_ptr<AuthorizationDelegate> empty_password(
    154         factory_.GetPasswordAuthorization(""));
    155     result = SetHierarchyAuthorization(TPM_RH_PLATFORM,
    156                                        kPlatformPassword,
    157                                        empty_password.get());
    158     if (GetFormatOneError(result) == TPM_RC_BAD_AUTH) {
    159       // Most likely the platform password has already been set.
    160       result = TPM_RC_SUCCESS;
    161     }
    162     if (result != TPM_RC_SUCCESS) {
    163       LOG(ERROR) << __func__ << ": " << GetErrorString(result);
    164       return result;
    165     }
    166     result = AllocatePCR(kPlatformPassword);
    167     if (result != TPM_RC_SUCCESS) {
    168       LOG(ERROR) << __func__ << ": " << GetErrorString(result);
    169       return result;
    170     }
    171     scoped_ptr<AuthorizationDelegate> authorization(
    172         factory_.GetPasswordAuthorization(kPlatformPassword));
    173     result = DisablePlatformHierarchy(authorization.get());
    174     if (result != TPM_RC_SUCCESS) {
    175       LOG(ERROR) << __func__ << ": " << GetErrorString(result);
    176       return result;
    177     }
    178   }
    179   return TPM_RC_SUCCESS;
    180 }
    181 
    182 TPM_RC TpmUtilityImpl::AllocatePCR(const std::string& platform_password) {
    183   TPM_RC result;
    184   TPMI_YES_NO more_data = YES;
    185   TPMS_CAPABILITY_DATA capability_data;
    186   result = factory_.GetTpm()->GetCapabilitySync(
    187       TPM_CAP_PCRS, 0 /*property (not used)*/, 1 /*property_count*/, &more_data,
    188       &capability_data, nullptr /*authorization_delegate*/);
    189   if (result != TPM_RC_SUCCESS) {
    190     LOG(ERROR) << "Error querying PCRs: " << GetErrorString(result);
    191     return result;
    192   }
    193   TPML_PCR_SELECTION& existing_pcrs = capability_data.data.assigned_pcr;
    194   bool sha256_needed = true;
    195   std::vector<TPMI_ALG_HASH> pcr_banks_to_remove;
    196   for (uint32_t i = 0; i < existing_pcrs.count; ++i) {
    197     if (existing_pcrs.pcr_selections[i].hash == TPM_ALG_SHA256) {
    198       sha256_needed = false;
    199     } else {
    200       pcr_banks_to_remove.push_back(existing_pcrs.pcr_selections[i].hash);
    201     }
    202   }
    203   if (!sha256_needed && pcr_banks_to_remove.empty()) {
    204     return TPM_RC_SUCCESS;
    205   }
    206   TPML_PCR_SELECTION pcr_allocation;
    207   memset(&pcr_allocation, 0, sizeof(pcr_allocation));
    208   if (sha256_needed) {
    209     pcr_allocation.pcr_selections[pcr_allocation.count].hash = TPM_ALG_SHA256;
    210     pcr_allocation.pcr_selections[pcr_allocation.count].sizeof_select =
    211         PCR_SELECT_MIN;
    212     for (int i = 0; i < PCR_SELECT_MIN; ++i) {
    213       pcr_allocation.pcr_selections[pcr_allocation.count].pcr_select[i] = 0xff;
    214     }
    215     ++pcr_allocation.count;
    216   }
    217   for (auto pcr_type : pcr_banks_to_remove) {
    218     pcr_allocation.pcr_selections[pcr_allocation.count].hash = pcr_type;
    219     pcr_allocation.pcr_selections[pcr_allocation.count].sizeof_select =
    220         PCR_SELECT_MAX;
    221     ++pcr_allocation.count;
    222   }
    223   scoped_ptr<AuthorizationDelegate> platform_delegate(
    224       factory_.GetPasswordAuthorization(platform_password));
    225   TPMI_YES_NO allocation_success;
    226   uint32_t max_pcr;
    227   uint32_t size_needed;
    228   uint32_t size_available;
    229   result = factory_.GetTpm()->PCR_AllocateSync(TPM_RH_PLATFORM,
    230                                                NameFromHandle(TPM_RH_PLATFORM),
    231                                                pcr_allocation,
    232                                                &allocation_success,
    233                                                &max_pcr,
    234                                                &size_needed,
    235                                                &size_available,
    236                                                platform_delegate.get());
    237   if (result != TPM_RC_SUCCESS) {
    238     LOG(ERROR) << "Error allocating PCRs: " << GetErrorString(result);
    239     return result;
    240   }
    241   if (allocation_success != YES) {
    242     LOG(ERROR) << "PCR allocation unsuccessful.";
    243     return TPM_RC_FAILURE;
    244   }
    245   return TPM_RC_SUCCESS;
    246 }
    247 
    248 TPM_RC TpmUtilityImpl::TakeOwnership(const std::string& owner_password,
    249                                      const std::string& endorsement_password,
    250                                      const std::string& lockout_password) {
    251   // First we set the storage hierarchy authorization to the well know default
    252   // password.
    253   TPM_RC result = TPM_RC_SUCCESS;
    254   result = SetKnownOwnerPassword(kWellKnownPassword);
    255   if (result != TPM_RC_SUCCESS) {
    256     LOG(ERROR) << "Error injecting known password: " << GetErrorString(result);
    257     return result;
    258   }
    259 
    260   result = CreateStorageRootKeys(kWellKnownPassword);
    261   if (result) {
    262     LOG(ERROR) << "Error creating SRKs: " << GetErrorString(result);
    263     return result;
    264   }
    265   result = CreateSaltingKey(kWellKnownPassword);
    266   if (result) {
    267     LOG(ERROR) << "Error creating salting key: "
    268                << GetErrorString(result);
    269     return result;
    270   }
    271 
    272   scoped_ptr<HmacSession> session = factory_.GetHmacSession();
    273   result = session->StartUnboundSession(true);
    274   if (result != TPM_RC_SUCCESS) {
    275     LOG(ERROR) << "Error initializing AuthorizationSession: "
    276                << GetErrorString(result);
    277     return result;
    278   }
    279   scoped_ptr<TpmState> tpm_state(factory_.GetTpmState());
    280   result = tpm_state->Initialize();
    281   session->SetEntityAuthorizationValue("");
    282   session->SetFutureAuthorizationValue(endorsement_password);
    283   if (!tpm_state->IsEndorsementPasswordSet()) {
    284     result = SetHierarchyAuthorization(TPM_RH_ENDORSEMENT,
    285                                        endorsement_password,
    286                                        session->GetDelegate());
    287     if (result) {
    288       LOG(ERROR) << __func__ << ": " << GetErrorString(result);
    289       return result;
    290     }
    291   }
    292   session->SetFutureAuthorizationValue(lockout_password);
    293   if (!tpm_state->IsLockoutPasswordSet()) {
    294     result = SetHierarchyAuthorization(TPM_RH_LOCKOUT,
    295                                        lockout_password,
    296                                        session->GetDelegate());
    297     if (result) {
    298       LOG(ERROR) << __func__ << ": " << GetErrorString(result);
    299       return result;
    300     }
    301   }
    302   // We take ownership of owner hierarchy last.
    303   session->SetEntityAuthorizationValue(kWellKnownPassword);
    304   session->SetFutureAuthorizationValue(owner_password);
    305   result = SetHierarchyAuthorization(TPM_RH_OWNER,
    306                                      owner_password,
    307                                      session->GetDelegate());
    308   if ((GetFormatOneError(result) == TPM_RC_BAD_AUTH) &&
    309       tpm_state->IsOwnerPasswordSet()) {
    310     LOG(WARNING) << "Error changing owner password. This probably because "
    311                  << "ownership is already taken.";
    312     return TPM_RC_SUCCESS;
    313   } else if (result != TPM_RC_SUCCESS) {
    314     LOG(ERROR) << "Error changing owner authorization: "
    315                << GetErrorString(result);
    316     return result;
    317   }
    318   return TPM_RC_SUCCESS;
    319 }
    320 
    321 TPM_RC TpmUtilityImpl::StirRandom(const std::string& entropy_data,
    322                                   AuthorizationDelegate* delegate) {
    323   std::string digest = crypto::SHA256HashString(entropy_data);
    324   TPM2B_SENSITIVE_DATA random_bytes = Make_TPM2B_SENSITIVE_DATA(digest);
    325   return factory_.GetTpm()->StirRandomSync(random_bytes, delegate);
    326 }
    327 
    328 TPM_RC TpmUtilityImpl::GenerateRandom(size_t num_bytes,
    329                                       AuthorizationDelegate* delegate,
    330                                       std::string* random_data) {
    331   CHECK(random_data);
    332   size_t bytes_left = num_bytes;
    333   random_data->clear();
    334   TPM_RC rc;
    335   TPM2B_DIGEST digest;
    336   while (bytes_left > 0) {
    337     rc = factory_.GetTpm()->GetRandomSync(bytes_left,
    338                                           &digest,
    339                                           delegate);
    340     if (rc) {
    341       LOG(ERROR) << "Error getting random data from tpm.";
    342       return rc;
    343     }
    344     random_data->append(StringFrom_TPM2B_DIGEST(digest));
    345     bytes_left -= digest.size;
    346   }
    347   CHECK_EQ(random_data->size(), num_bytes);
    348   return TPM_RC_SUCCESS;
    349 }
    350 
    351 TPM_RC TpmUtilityImpl::ExtendPCR(int pcr_index,
    352                                  const std::string& extend_data,
    353                                  AuthorizationDelegate* delegate) {
    354   if (pcr_index < 0 || pcr_index >= IMPLEMENTATION_PCR) {
    355     LOG(ERROR) << "Using a PCR index that isnt implemented.";
    356     return TPM_RC_FAILURE;
    357   }
    358   TPM_HANDLE pcr_handle = HR_PCR + pcr_index;
    359   std::string pcr_name = NameFromHandle(pcr_handle);
    360   TPML_DIGEST_VALUES digests;
    361   digests.count = 1;
    362   digests.digests[0].hash_alg = TPM_ALG_SHA256;
    363   crypto::SHA256HashString(extend_data,
    364                            digests.digests[0].digest.sha256,
    365                            crypto::kSHA256Length);
    366   return factory_.GetTpm()->PCR_ExtendSync(pcr_handle,
    367                                            pcr_name,
    368                                            digests,
    369                                            delegate);
    370 }
    371 
    372 TPM_RC TpmUtilityImpl::ReadPCR(int pcr_index, std::string* pcr_value) {
    373   TPML_PCR_SELECTION pcr_select_in;
    374   uint32_t pcr_update_counter;
    375   TPML_PCR_SELECTION pcr_select_out;
    376   TPML_DIGEST pcr_values;
    377   // This process of selecting pcrs is highlighted in TPM 2.0 Library Spec
    378   // Part 2 (Section 10.5 - PCR structures).
    379   uint8_t pcr_select_index = pcr_index / 8;
    380   uint8_t pcr_select_byte = 1 << (pcr_index % 8);
    381   pcr_select_in.count = 1;
    382   pcr_select_in.pcr_selections[0].hash = TPM_ALG_SHA256;
    383   pcr_select_in.pcr_selections[0].sizeof_select = PCR_SELECT_MIN;
    384   pcr_select_in.pcr_selections[0].pcr_select[pcr_select_index] =
    385       pcr_select_byte;
    386 
    387   TPM_RC rc = factory_.GetTpm()->PCR_ReadSync(pcr_select_in,
    388                                               &pcr_update_counter,
    389                                               &pcr_select_out,
    390                                               &pcr_values,
    391                                               nullptr);
    392   if (rc) {
    393     LOG(INFO) << "Error trying to read a pcr: " << GetErrorString(rc);
    394     return rc;
    395   }
    396   if (pcr_select_out.count != 1 ||
    397       pcr_select_out.pcr_selections[0].sizeof_select <
    398       (pcr_select_index + 1) ||
    399       pcr_select_out.pcr_selections[0].pcr_select[pcr_select_index] !=
    400       pcr_select_byte) {
    401     LOG(ERROR) << "TPM did not return the requested PCR";
    402     return TPM_RC_FAILURE;
    403   }
    404   CHECK_GE(pcr_values.count, 1U);
    405   pcr_value->assign(StringFrom_TPM2B_DIGEST(pcr_values.digests[0]));
    406   return TPM_RC_SUCCESS;
    407 }
    408 
    409 TPM_RC TpmUtilityImpl::AsymmetricEncrypt(TPM_HANDLE key_handle,
    410                                          TPM_ALG_ID scheme,
    411                                          TPM_ALG_ID hash_alg,
    412                                          const std::string& plaintext,
    413                                          AuthorizationDelegate* delegate,
    414                                          std::string* ciphertext) {
    415   TPMT_RSA_DECRYPT in_scheme;
    416   if (hash_alg == TPM_ALG_NULL) {
    417     hash_alg = TPM_ALG_SHA256;
    418   }
    419   if (scheme == TPM_ALG_RSAES) {
    420     in_scheme.scheme = TPM_ALG_RSAES;
    421   } else if (scheme == TPM_ALG_OAEP || scheme == TPM_ALG_NULL) {
    422     in_scheme.scheme = TPM_ALG_OAEP;
    423     in_scheme.details.oaep.hash_alg = hash_alg;
    424   } else {
    425     LOG(ERROR) << "Invalid Signing scheme used.";
    426     return SAPI_RC_BAD_PARAMETER;
    427   }
    428 
    429   TPMT_PUBLIC public_area;
    430   TPM_RC result = GetKeyPublicArea(key_handle, &public_area);
    431   if (result != TPM_RC_SUCCESS) {
    432     LOG(ERROR) << "Error finding public area for: " << key_handle;
    433     return result;
    434   } else if (public_area.type != TPM_ALG_RSA) {
    435     LOG(ERROR) << "Key handle given is not an RSA key";
    436     return SAPI_RC_BAD_PARAMETER;
    437   } else if ((public_area.object_attributes & kDecrypt) == 0) {
    438     LOG(ERROR) << "Key handle given is not a decryption key";
    439     return SAPI_RC_BAD_PARAMETER;
    440   }
    441   if ((public_area.object_attributes & kRestricted) != 0) {
    442     LOG(ERROR) << "Cannot use RSAES for encryption with a restricted key";
    443     return SAPI_RC_BAD_PARAMETER;
    444   }
    445   std::string key_name;
    446   result = ComputeKeyName(public_area, &key_name);
    447   if (result != TPM_RC_SUCCESS) {
    448     LOG(ERROR) << "Error computing key name for: " << key_handle;
    449     return result;
    450   }
    451 
    452   TPM2B_DATA label;
    453   label.size = 0;
    454   TPM2B_PUBLIC_KEY_RSA in_message = Make_TPM2B_PUBLIC_KEY_RSA(plaintext);
    455   TPM2B_PUBLIC_KEY_RSA out_message;
    456   result = factory_.GetTpm()->RSA_EncryptSync(key_handle,
    457                                               key_name,
    458                                               in_message,
    459                                               in_scheme,
    460                                               label,
    461                                               &out_message,
    462                                               delegate);
    463   if (result != TPM_RC_SUCCESS) {
    464     LOG(ERROR) << "Error performing RSA encrypt: "
    465                << GetErrorString(result);
    466     return result;
    467   }
    468   ciphertext->assign(StringFrom_TPM2B_PUBLIC_KEY_RSA(out_message));
    469   return TPM_RC_SUCCESS;
    470 }
    471 
    472 TPM_RC TpmUtilityImpl::AsymmetricDecrypt(TPM_HANDLE key_handle,
    473                                          TPM_ALG_ID scheme,
    474                                          TPM_ALG_ID hash_alg,
    475                                          const std::string& ciphertext,
    476                                          AuthorizationDelegate* delegate,
    477                                          std::string* plaintext) {
    478   TPMT_RSA_DECRYPT in_scheme;
    479   if (hash_alg == TPM_ALG_NULL) {
    480     hash_alg = TPM_ALG_SHA256;
    481   }
    482   if (scheme == TPM_ALG_RSAES) {
    483     in_scheme.scheme = TPM_ALG_RSAES;
    484   } else if (scheme == TPM_ALG_OAEP || scheme == TPM_ALG_NULL) {
    485     in_scheme.scheme = TPM_ALG_OAEP;
    486     in_scheme.details.oaep.hash_alg = hash_alg;
    487   } else {
    488     LOG(ERROR) << "Invalid Signing scheme used.";
    489     return SAPI_RC_BAD_PARAMETER;
    490   }
    491   TPM_RC result;
    492   if (delegate == nullptr) {
    493     result = SAPI_RC_INVALID_SESSIONS;
    494     LOG(ERROR) << "This method needs a valid authorization delegate: "
    495                << GetErrorString(result);
    496     return result;
    497   }
    498   TPMT_PUBLIC public_area;
    499   result = GetKeyPublicArea(key_handle, &public_area);
    500   if (result) {
    501     LOG(ERROR) << "Error finding public area for: " << key_handle;
    502     return result;
    503   } else if (public_area.type != TPM_ALG_RSA) {
    504     LOG(ERROR) << "Key handle given is not an RSA key";
    505     return SAPI_RC_BAD_PARAMETER;
    506   } else if ((public_area.object_attributes & kDecrypt) == 0) {
    507     LOG(ERROR) << "Key handle given is not a decryption key";
    508     return SAPI_RC_BAD_PARAMETER;
    509   }
    510   if ((public_area.object_attributes & kRestricted) != 0) {
    511     LOG(ERROR) << "Cannot use RSAES for encryption with a restricted key";
    512     return SAPI_RC_BAD_PARAMETER;
    513   }
    514   std::string key_name;
    515   result = ComputeKeyName(public_area, &key_name);
    516   if (result) {
    517     LOG(ERROR) << "Error computing key name for: " << key_handle;
    518     return result;
    519   }
    520 
    521   TPM2B_DATA label;
    522   label.size = 0;
    523   TPM2B_PUBLIC_KEY_RSA in_message = Make_TPM2B_PUBLIC_KEY_RSA(ciphertext);
    524   TPM2B_PUBLIC_KEY_RSA out_message;
    525   result = factory_.GetTpm()->RSA_DecryptSync(key_handle,
    526                                               key_name,
    527                                               in_message,
    528                                               in_scheme,
    529                                               label,
    530                                               &out_message,
    531                                               delegate);
    532   if (result) {
    533     LOG(ERROR) << "Error performing RSA decrypt: "
    534                << GetErrorString(result);
    535     return result;
    536   }
    537   plaintext->assign(StringFrom_TPM2B_PUBLIC_KEY_RSA(out_message));
    538   return TPM_RC_SUCCESS;
    539 }
    540 
    541 TPM_RC TpmUtilityImpl::Sign(TPM_HANDLE key_handle,
    542                             TPM_ALG_ID scheme,
    543                             TPM_ALG_ID hash_alg,
    544                             const std::string& plaintext,
    545                             AuthorizationDelegate* delegate,
    546                             std::string* signature) {
    547   TPMT_SIG_SCHEME in_scheme;
    548   if (hash_alg == TPM_ALG_NULL) {
    549     hash_alg = TPM_ALG_SHA256;
    550   }
    551   if (scheme == TPM_ALG_RSAPSS) {
    552     in_scheme.scheme = TPM_ALG_RSAPSS;
    553     in_scheme.details.rsapss.hash_alg = hash_alg;
    554   } else if (scheme == TPM_ALG_RSASSA || scheme == TPM_ALG_NULL) {
    555     in_scheme.scheme = TPM_ALG_RSASSA;
    556     in_scheme.details.rsassa.hash_alg = hash_alg;
    557   } else {
    558     LOG(ERROR) << "Invalid Signing scheme used.";
    559     return SAPI_RC_BAD_PARAMETER;
    560   }
    561   TPM_RC result;
    562   if (delegate == nullptr) {
    563     result = SAPI_RC_INVALID_SESSIONS;
    564     LOG(ERROR) << "This method needs a valid authorization delegate: "
    565                << GetErrorString(result);
    566     return result;
    567   }
    568   TPMT_PUBLIC public_area;
    569   result = GetKeyPublicArea(key_handle, &public_area);
    570   if (result) {
    571     LOG(ERROR) << "Error finding public area for: " << key_handle;
    572     return result;
    573   } else if (public_area.type != TPM_ALG_RSA) {
    574     LOG(ERROR) << "Key handle given is not an RSA key";
    575     return SAPI_RC_BAD_PARAMETER;
    576   } else if ((public_area.object_attributes & kSign) == 0) {
    577     LOG(ERROR) << "Key handle given is not a signging key";
    578     return SAPI_RC_BAD_PARAMETER;
    579   } else if ((public_area.object_attributes & kRestricted) != 0) {
    580     LOG(ERROR) << "Key handle references a restricted key";
    581     return SAPI_RC_BAD_PARAMETER;
    582   }
    583 
    584   std::string key_name;
    585   result = ComputeKeyName(public_area, &key_name);
    586   if (result) {
    587     LOG(ERROR) << "Error computing key name for: " << key_handle;
    588     return result;
    589   }
    590   std::string digest = HashString(plaintext, hash_alg);
    591   TPM2B_DIGEST tpm_digest = Make_TPM2B_DIGEST(digest);
    592   TPMT_SIGNATURE signature_out;
    593   TPMT_TK_HASHCHECK validation;
    594   validation.tag = TPM_ST_HASHCHECK;
    595   validation.hierarchy = TPM_RH_NULL;
    596   validation.digest.size = 0;
    597   result = factory_.GetTpm()->SignSync(key_handle,
    598                                        key_name,
    599                                        tpm_digest,
    600                                        in_scheme,
    601                                        validation,
    602                                        &signature_out,
    603                                        delegate);
    604   if (result) {
    605     LOG(ERROR) << "Error signing digest: " << GetErrorString(result);
    606     return result;
    607   }
    608   if (scheme == TPM_ALG_RSAPSS) {
    609     signature->resize(signature_out.signature.rsapss.sig.size);
    610     signature->assign(StringFrom_TPM2B_PUBLIC_KEY_RSA(
    611         signature_out.signature.rsapss.sig));
    612   } else {
    613     signature->resize(signature_out.signature.rsassa.sig.size);
    614     signature->assign(StringFrom_TPM2B_PUBLIC_KEY_RSA(
    615         signature_out.signature.rsassa.sig));
    616   }
    617   return TPM_RC_SUCCESS;
    618 }
    619 
    620 TPM_RC TpmUtilityImpl::Verify(TPM_HANDLE key_handle,
    621                               TPM_ALG_ID scheme,
    622                               TPM_ALG_ID hash_alg,
    623                               const std::string& plaintext,
    624                               const std::string& signature,
    625                               AuthorizationDelegate* delegate) {
    626   TPMT_PUBLIC public_area;
    627   TPM_RC return_code = GetKeyPublicArea(key_handle, &public_area);
    628   if (return_code) {
    629     LOG(ERROR) << "Error finding public area for: " << key_handle;
    630     return return_code;
    631   } else if (public_area.type != TPM_ALG_RSA) {
    632     LOG(ERROR) << "Key handle given is not an RSA key";
    633     return SAPI_RC_BAD_PARAMETER;
    634   } else if ((public_area.object_attributes & kSign) == 0) {
    635     LOG(ERROR) << "Key handle given is not a signing key";
    636     return SAPI_RC_BAD_PARAMETER;
    637   } else if ((public_area.object_attributes & kRestricted) != 0) {
    638     LOG(ERROR) << "Cannot use RSAPSS for signing with a restricted key";
    639     return SAPI_RC_BAD_PARAMETER;
    640   }
    641   if (hash_alg == TPM_ALG_NULL) {
    642     hash_alg = TPM_ALG_SHA256;
    643   }
    644 
    645   TPMT_SIGNATURE signature_in;
    646   if (scheme == TPM_ALG_RSAPSS) {
    647     signature_in.sig_alg = TPM_ALG_RSAPSS;
    648     signature_in.signature.rsapss.hash = hash_alg;
    649     signature_in.signature.rsapss.sig = Make_TPM2B_PUBLIC_KEY_RSA(signature);
    650   } else if (scheme == TPM_ALG_NULL || scheme == TPM_ALG_RSASSA) {
    651     signature_in.sig_alg = TPM_ALG_RSASSA;
    652     signature_in.signature.rsassa.hash = hash_alg;
    653     signature_in.signature.rsassa.sig = Make_TPM2B_PUBLIC_KEY_RSA(signature);
    654   } else {
    655     LOG(ERROR) << "Invalid scheme used to verify signature.";
    656     return SAPI_RC_BAD_PARAMETER;
    657   }
    658   std::string key_name;
    659   TPMT_TK_VERIFIED verified;
    660   std::string digest = HashString(plaintext, hash_alg);
    661   TPM2B_DIGEST tpm_digest = Make_TPM2B_DIGEST(digest);
    662   return_code = factory_.GetTpm()->VerifySignatureSync(key_handle,
    663                                                        key_name,
    664                                                        tpm_digest,
    665                                                        signature_in,
    666                                                        &verified,
    667                                                        delegate);
    668   if (return_code == TPM_RC_SIGNATURE) {
    669     LOG(WARNING) << "Incorrect signature for given digest.";
    670     return TPM_RC_SIGNATURE;
    671   } else if (return_code && return_code != TPM_RC_SIGNATURE) {
    672     LOG(ERROR) << "Error verifying signature: " << GetErrorString(return_code);
    673     return return_code;
    674   }
    675   return TPM_RC_SUCCESS;
    676 }
    677 
    678 TPM_RC TpmUtilityImpl::CertifyCreation(TPM_HANDLE key_handle,
    679                                        const std::string& creation_blob) {
    680   TPM2B_CREATION_DATA creation_data;
    681   TPM2B_DIGEST creation_hash;
    682   TPMT_TK_CREATION creation_ticket;
    683   if (!factory_.GetBlobParser()->ParseCreationBlob(creation_blob,
    684                                                    &creation_data,
    685                                                    &creation_hash,
    686                                                    &creation_ticket)) {
    687     LOG(ERROR) << "Error parsing CreationBlob.";
    688     return SAPI_RC_BAD_PARAMETER;
    689   }
    690   TPM2B_DATA qualifying_data;
    691   qualifying_data.size = 0;
    692   TPMT_SIG_SCHEME in_scheme;
    693   in_scheme.scheme = TPM_ALG_NULL;
    694   TPM2B_ATTEST certify_info;
    695   TPMT_SIGNATURE signature;
    696   scoped_ptr<AuthorizationDelegate> delegate =
    697       factory_.GetPasswordAuthorization("");
    698   TPM_RC result = factory_.GetTpm()->CertifyCreationSync(TPM_RH_NULL,
    699                                                          "",
    700                                                          key_handle,
    701                                                          "",
    702                                                          qualifying_data,
    703                                                          creation_hash,
    704                                                          in_scheme,
    705                                                          creation_ticket,
    706                                                          &certify_info,
    707                                                          &signature,
    708                                                          delegate.get());
    709   if (result != TPM_RC_SUCCESS) {
    710     LOG(ERROR) << "Error certifying key creation: " << GetErrorString(result);
    711     return result;
    712   }
    713   return TPM_RC_SUCCESS;
    714 }
    715 
    716 TPM_RC TpmUtilityImpl::ChangeKeyAuthorizationData(
    717     TPM_HANDLE key_handle,
    718     const std::string& new_password,
    719     AuthorizationDelegate* delegate,
    720     std::string* key_blob) {
    721   TPM_RC result;
    722   if (delegate == nullptr) {
    723     result = SAPI_RC_INVALID_SESSIONS;
    724     LOG(ERROR) << "This method needs a valid authorization delegate: "
    725                << GetErrorString(result);
    726     return result;
    727   }
    728   std::string key_name;
    729   std::string parent_name;
    730   result = GetKeyName(key_handle, &key_name);
    731   if (result != TPM_RC_SUCCESS) {
    732     LOG(ERROR) << "Error getting Key name for key_handle: "
    733                << GetErrorString(result);
    734     return result;
    735   }
    736   result = GetKeyName(kRSAStorageRootKey, &parent_name);
    737   if (result != TPM_RC_SUCCESS) {
    738     LOG(ERROR) << "Error getting Key name for RSA-SRK: "
    739                << GetErrorString(result);
    740     return result;
    741   }
    742   TPM2B_AUTH new_auth = Make_TPM2B_DIGEST(new_password);
    743   TPM2B_PRIVATE new_private_data;
    744   new_private_data.size = 0;
    745   result = factory_.GetTpm()->ObjectChangeAuthSync(key_handle,
    746                                                    key_name,
    747                                                    kRSAStorageRootKey,
    748                                                    parent_name,
    749                                                    new_auth,
    750                                                    &new_private_data,
    751                                                    delegate);
    752   if (result != TPM_RC_SUCCESS) {
    753     LOG(ERROR) << "Error changing object authorization data: "
    754                << GetErrorString(result);
    755     return result;
    756   }
    757   if (key_blob) {
    758     TPMT_PUBLIC public_data;
    759     result = GetKeyPublicArea(key_handle, &public_data);
    760     if (result != TPM_RC_SUCCESS) {
    761       return result;
    762     }
    763     if (!factory_.GetBlobParser()->SerializeKeyBlob(
    764         Make_TPM2B_PUBLIC(public_data), new_private_data, key_blob)) {
    765       return SAPI_RC_BAD_TCTI_STRUCTURE;
    766     }
    767   }
    768   return TPM_RC_SUCCESS;
    769 }
    770 
    771 TPM_RC TpmUtilityImpl::ImportRSAKey(AsymmetricKeyUsage key_type,
    772                                     const std::string& modulus,
    773                                     uint32_t public_exponent,
    774                                     const std::string& prime_factor,
    775                                     const std::string& password,
    776                                     AuthorizationDelegate* delegate,
    777                                     std::string* key_blob) {
    778   TPM_RC result;
    779   if (delegate == nullptr) {
    780     result = SAPI_RC_INVALID_SESSIONS;
    781     LOG(ERROR) << "This method needs a valid authorization delegate: "
    782                << GetErrorString(result);
    783     return result;
    784   }
    785   std::string parent_name;
    786   result = GetKeyName(kRSAStorageRootKey, &parent_name);
    787   if (result != TPM_RC_SUCCESS) {
    788     LOG(ERROR) << "Error getting Key name for RSA-SRK: "
    789                << GetErrorString(result);
    790     return result;
    791   }
    792   TPMT_PUBLIC public_area = CreateDefaultPublicArea(TPM_ALG_RSA);
    793   public_area.object_attributes = kUserWithAuth | kNoDA;
    794   switch (key_type) {
    795     case AsymmetricKeyUsage::kDecryptKey:
    796       public_area.object_attributes |= kDecrypt;
    797       break;
    798     case AsymmetricKeyUsage::kSignKey:
    799       public_area.object_attributes |= kSign;
    800       break;
    801     case AsymmetricKeyUsage::kDecryptAndSignKey:
    802       public_area.object_attributes |= (kSign | kDecrypt);
    803       break;
    804   }
    805   public_area.parameters.rsa_detail.key_bits = modulus.size() * 8;
    806   public_area.parameters.rsa_detail.exponent = public_exponent;
    807   public_area.unique.rsa = Make_TPM2B_PUBLIC_KEY_RSA(modulus);
    808   TPM2B_DATA encryption_key;
    809   encryption_key.size = kAesKeySize;
    810   CHECK_EQ(RAND_bytes(encryption_key.buffer, encryption_key.size), 1) <<
    811       "Error generating a cryptographically random Aes Key.";
    812   TPM2B_PUBLIC public_data = Make_TPM2B_PUBLIC(public_area);
    813   TPM2B_ENCRYPTED_SECRET in_sym_seed = Make_TPM2B_ENCRYPTED_SECRET("");
    814   TPMT_SYM_DEF_OBJECT symmetric_alg;
    815   symmetric_alg.algorithm = TPM_ALG_AES;
    816   symmetric_alg.key_bits.aes = kAesKeySize * 8;
    817   symmetric_alg.mode.aes = TPM_ALG_CFB;
    818   TPMT_SENSITIVE in_sensitive;
    819   in_sensitive.sensitive_type = TPM_ALG_RSA;
    820   in_sensitive.auth_value = Make_TPM2B_DIGEST(password);
    821   in_sensitive.seed_value = Make_TPM2B_DIGEST("");
    822   in_sensitive.sensitive.rsa = Make_TPM2B_PRIVATE_KEY_RSA(prime_factor);
    823   TPM2B_PRIVATE private_data;
    824   result = EncryptPrivateData(in_sensitive, public_area,
    825                               &private_data, &encryption_key);
    826   if (result != TPM_RC_SUCCESS) {
    827     LOG(ERROR) << "Error creating encrypted private struct: "
    828                << GetErrorString(result);
    829     return result;
    830   }
    831   TPM2B_PRIVATE tpm_private_data;
    832   tpm_private_data.size = 0;
    833   result = factory_.GetTpm()->ImportSync(kRSAStorageRootKey,
    834                                          parent_name,
    835                                          encryption_key,
    836                                          public_data,
    837                                          private_data,
    838                                          in_sym_seed,
    839                                          symmetric_alg,
    840                                          &tpm_private_data,
    841                                          delegate);
    842   if (result != TPM_RC_SUCCESS) {
    843     LOG(ERROR) << "Error importing key: " << GetErrorString(result);
    844     return result;
    845   }
    846   if (key_blob) {
    847     if (!factory_.GetBlobParser()->SerializeKeyBlob(
    848         public_data, tpm_private_data, key_blob)) {
    849       return SAPI_RC_BAD_TCTI_STRUCTURE;
    850     }
    851   }
    852   return TPM_RC_SUCCESS;
    853 }
    854 
    855 TPM_RC TpmUtilityImpl::CreateRSAKeyPair(AsymmetricKeyUsage key_type,
    856                                         int modulus_bits,
    857                                         uint32_t public_exponent,
    858                                         const std::string& password,
    859                                         const std::string& policy_digest,
    860                                         bool use_only_policy_authorization,
    861                                         int creation_pcr_index,
    862                                         AuthorizationDelegate* delegate,
    863                                         std::string* key_blob,
    864                                         std::string* creation_blob) {
    865   CHECK(key_blob);
    866   TPM_RC result;
    867   if (delegate == nullptr) {
    868     result = SAPI_RC_INVALID_SESSIONS;
    869     LOG(ERROR) << "This method needs a valid authorization delegate: "
    870                << GetErrorString(result);
    871     return result;
    872   }
    873   std::string parent_name;
    874   result = GetKeyName(kRSAStorageRootKey, &parent_name);
    875   if (result != TPM_RC_SUCCESS) {
    876     LOG(ERROR) << "Error getting Key name for RSA-SRK: "
    877                << GetErrorString(result);
    878     return result;
    879   }
    880   TPMT_PUBLIC public_area = CreateDefaultPublicArea(TPM_ALG_RSA);
    881   public_area.auth_policy = Make_TPM2B_DIGEST(policy_digest);
    882   public_area.object_attributes |=
    883       (kSensitiveDataOrigin | kUserWithAuth | kNoDA);
    884   switch (key_type) {
    885     case AsymmetricKeyUsage::kDecryptKey:
    886       public_area.object_attributes |= kDecrypt;
    887       break;
    888     case AsymmetricKeyUsage::kSignKey:
    889       public_area.object_attributes |= kSign;
    890       break;
    891     case AsymmetricKeyUsage::kDecryptAndSignKey:
    892       public_area.object_attributes |= (kSign | kDecrypt);
    893       break;
    894   }
    895   if (use_only_policy_authorization && !policy_digest.empty()) {
    896     public_area.object_attributes |= kAdminWithPolicy;
    897     public_area.object_attributes &= (~kUserWithAuth);
    898   }
    899   public_area.parameters.rsa_detail.key_bits = modulus_bits;
    900   public_area.parameters.rsa_detail.exponent = public_exponent;
    901   TPML_PCR_SELECTION creation_pcrs = {};
    902   if (creation_pcr_index == kNoCreationPCR) {
    903     creation_pcrs.count = 0;
    904   } else if (creation_pcr_index < 0 ||
    905              creation_pcr_index > (PCR_SELECT_MIN * 8)) {
    906     LOG(ERROR) << "Creation PCR index is not within the allocated bank.";
    907     return SAPI_RC_BAD_PARAMETER;
    908   } else {
    909     creation_pcrs.count = 1;
    910     creation_pcrs.pcr_selections[0].hash = TPM_ALG_SHA256;
    911     creation_pcrs.pcr_selections[0].sizeof_select = PCR_SELECT_MIN;
    912     creation_pcrs.pcr_selections[0].pcr_select[creation_pcr_index / 8] =
    913         1 << (creation_pcr_index % 8);
    914   }
    915   TPMS_SENSITIVE_CREATE sensitive;
    916   sensitive.user_auth = Make_TPM2B_DIGEST(password);
    917   sensitive.data = Make_TPM2B_SENSITIVE_DATA("");
    918   TPM2B_SENSITIVE_CREATE sensitive_create = Make_TPM2B_SENSITIVE_CREATE(
    919       sensitive);
    920   TPM2B_DATA outside_info = Make_TPM2B_DATA("");
    921   TPM2B_PUBLIC out_public;
    922   out_public.size = 0;
    923   TPM2B_PRIVATE out_private;
    924   out_private.size = 0;
    925   TPM2B_CREATION_DATA creation_data;
    926   TPM2B_DIGEST creation_hash;
    927   TPMT_TK_CREATION creation_ticket;
    928   result = factory_.GetTpm()->CreateSync(kRSAStorageRootKey,
    929                                          parent_name,
    930                                          sensitive_create,
    931                                          Make_TPM2B_PUBLIC(public_area),
    932                                          outside_info,
    933                                          creation_pcrs,
    934                                          &out_private,
    935                                          &out_public,
    936                                          &creation_data,
    937                                          &creation_hash,
    938                                          &creation_ticket,
    939                                          delegate);
    940   if (result != TPM_RC_SUCCESS) {
    941     LOG(ERROR) << "Error creating RSA key: " << GetErrorString(result);
    942     return result;
    943   }
    944   if (!factory_.GetBlobParser()->SerializeKeyBlob(
    945       out_public, out_private, key_blob)) {
    946     return SAPI_RC_BAD_TCTI_STRUCTURE;
    947   }
    948   if (creation_blob) {
    949     if (!factory_.GetBlobParser()->SerializeCreationBlob(
    950         creation_data, creation_hash, creation_ticket, creation_blob)) {
    951       return SAPI_RC_BAD_TCTI_STRUCTURE;
    952     }
    953   }
    954   return TPM_RC_SUCCESS;
    955 }
    956 
    957 TPM_RC TpmUtilityImpl::LoadKey(const std::string& key_blob,
    958                                AuthorizationDelegate* delegate,
    959                                TPM_HANDLE* key_handle) {
    960   CHECK(key_handle);
    961   TPM_RC result;
    962   if (delegate == nullptr) {
    963     result = SAPI_RC_INVALID_SESSIONS;
    964     LOG(ERROR) << "This method needs a valid authorization delegate: "
    965                << GetErrorString(result);
    966     return result;
    967   }
    968   std::string parent_name;
    969   result = GetKeyName(kRSAStorageRootKey, &parent_name);
    970   if (result != TPM_RC_SUCCESS) {
    971     LOG(ERROR) << "Error getting parent key name: " << GetErrorString(result);
    972     return result;
    973   }
    974   TPM2B_PUBLIC in_public;
    975   TPM2B_PRIVATE in_private;
    976   if (!factory_.GetBlobParser()->ParseKeyBlob(
    977       key_blob, &in_public, &in_private)) {
    978     return SAPI_RC_BAD_TCTI_STRUCTURE;
    979   }
    980   TPM2B_NAME key_name;
    981   key_name.size = 0;
    982   result = factory_.GetTpm()->LoadSync(kRSAStorageRootKey,
    983                                        parent_name,
    984                                        in_private,
    985                                        in_public,
    986                                        key_handle,
    987                                        &key_name,
    988                                        delegate);
    989   if (result != TPM_RC_SUCCESS) {
    990     LOG(ERROR) << "Error loading key: " << GetErrorString(result);
    991     return result;
    992   }
    993   return TPM_RC_SUCCESS;
    994 }
    995 
    996 TPM_RC TpmUtilityImpl::GetKeyName(TPM_HANDLE handle, std::string* name) {
    997   CHECK(name);
    998   TPM_RC result;
    999   TPMT_PUBLIC public_data;
   1000   result = GetKeyPublicArea(handle, &public_data);
   1001   if (result != TPM_RC_SUCCESS) {
   1002     LOG(ERROR) << "Error fetching public info: " << GetErrorString(result);
   1003     return result;
   1004   }
   1005   result = ComputeKeyName(public_data, name);
   1006   if (result != TPM_RC_SUCCESS) {
   1007     LOG(ERROR) << "Error computing key name: " << GetErrorString(result);
   1008     return TPM_RC_SUCCESS;
   1009   }
   1010   return TPM_RC_SUCCESS;
   1011 }
   1012 
   1013 TPM_RC TpmUtilityImpl::GetKeyPublicArea(TPM_HANDLE handle,
   1014                                         TPMT_PUBLIC* public_data) {
   1015   CHECK(public_data);
   1016   TPM2B_NAME out_name;
   1017   TPM2B_PUBLIC public_area;
   1018   TPM2B_NAME qualified_name;
   1019   std::string handle_name;  // Unused
   1020   TPM_RC return_code = factory_.GetTpm()->ReadPublicSync(handle,
   1021                                                          handle_name,
   1022                                                          &public_area,
   1023                                                          &out_name,
   1024                                                          &qualified_name,
   1025                                                          nullptr);
   1026   if (return_code) {
   1027     LOG(ERROR) << "Error getting public area for object: " << handle;
   1028     return return_code;
   1029   }
   1030   *public_data = public_area.public_area;
   1031   return TPM_RC_SUCCESS;
   1032 }
   1033 
   1034 TPM_RC TpmUtilityImpl::SealData(const std::string& data_to_seal,
   1035                                 const std::string& policy_digest,
   1036                                 AuthorizationDelegate* delegate,
   1037                                 std::string* sealed_data) {
   1038   CHECK(sealed_data);
   1039   TPM_RC result;
   1040   if (delegate == nullptr) {
   1041     result = SAPI_RC_INVALID_SESSIONS;
   1042     LOG(ERROR) << "This method needs a valid authorization delegate: "
   1043                << GetErrorString(result);
   1044     return result;
   1045   }
   1046   std::string parent_name;
   1047   result = GetKeyName(kRSAStorageRootKey, &parent_name);
   1048   if (result != TPM_RC_SUCCESS) {
   1049     LOG(ERROR) << "Error getting Key name for RSA-SRK: "
   1050                << GetErrorString(result);
   1051     return result;
   1052   }
   1053   // We seal data to the TPM by creating a KEYEDHASH object with sign and
   1054   // decrypt attributes disabled.
   1055   TPMT_PUBLIC public_area = CreateDefaultPublicArea(TPM_ALG_KEYEDHASH);
   1056   public_area.auth_policy = Make_TPM2B_DIGEST(policy_digest);
   1057   public_area.object_attributes = kAdminWithPolicy | kNoDA;
   1058   public_area.unique.keyed_hash.size = 0;
   1059   TPML_PCR_SELECTION creation_pcrs = {};
   1060   TPMS_SENSITIVE_CREATE sensitive;
   1061   sensitive.user_auth = Make_TPM2B_DIGEST("");
   1062   sensitive.data = Make_TPM2B_SENSITIVE_DATA(data_to_seal);
   1063   TPM2B_SENSITIVE_CREATE sensitive_create = Make_TPM2B_SENSITIVE_CREATE(
   1064       sensitive);
   1065   TPM2B_DATA outside_info = Make_TPM2B_DATA("");
   1066   TPM2B_PUBLIC out_public;
   1067   out_public.size = 0;
   1068   TPM2B_PRIVATE out_private;
   1069   out_private.size = 0;
   1070   TPM2B_CREATION_DATA creation_data;
   1071   TPM2B_DIGEST creation_hash;
   1072   TPMT_TK_CREATION creation_ticket;
   1073   result = factory_.GetTpm()->CreateSync(kRSAStorageRootKey,
   1074                                          parent_name,
   1075                                          sensitive_create,
   1076                                          Make_TPM2B_PUBLIC(public_area),
   1077                                          outside_info,
   1078                                          creation_pcrs,
   1079                                          &out_private,
   1080                                          &out_public,
   1081                                          &creation_data,
   1082                                          &creation_hash,
   1083                                          &creation_ticket,
   1084                                          delegate);
   1085   if (result != TPM_RC_SUCCESS) {
   1086     LOG(ERROR) << "Error creating sealed object: " << GetErrorString(result);
   1087     return result;
   1088   }
   1089   if (!factory_.GetBlobParser()->SerializeKeyBlob(
   1090       out_public, out_private, sealed_data)) {
   1091     return SAPI_RC_BAD_TCTI_STRUCTURE;
   1092   }
   1093   return TPM_RC_SUCCESS;
   1094 }
   1095 
   1096 TPM_RC TpmUtilityImpl::UnsealData(const std::string& sealed_data,
   1097                                   AuthorizationDelegate* delegate,
   1098                                   std::string* unsealed_data) {
   1099   CHECK(unsealed_data);
   1100   TPM_RC result;
   1101   if (delegate == nullptr) {
   1102     result = SAPI_RC_INVALID_SESSIONS;
   1103     LOG(ERROR) << "This method needs a valid authorization delegate: "
   1104                << GetErrorString(result);
   1105     return result;
   1106   }
   1107   TPM_HANDLE object_handle;
   1108   scoped_ptr<AuthorizationDelegate> password_delegate =
   1109       factory_.GetPasswordAuthorization("");
   1110   result = LoadKey(sealed_data, password_delegate.get(), &object_handle);
   1111   if (result != TPM_RC_SUCCESS) {
   1112     LOG(ERROR) << "Error loading sealed object: " << GetErrorString(result);
   1113     return result;
   1114   }
   1115   ScopedKeyHandle sealed_object(factory_, object_handle);
   1116   std::string object_name;
   1117   result = GetKeyName(sealed_object.get(), &object_name);
   1118   if (result != TPM_RC_SUCCESS) {
   1119     LOG(ERROR) << "Error getting object name: " << GetErrorString(result);
   1120     return result;
   1121   }
   1122   TPM2B_SENSITIVE_DATA out_data;
   1123   result = factory_.GetTpm()->UnsealSync(sealed_object.get(), object_name,
   1124                                          &out_data, delegate);
   1125   if (result != TPM_RC_SUCCESS) {
   1126     LOG(ERROR) << "Error unsealing object: " << GetErrorString(result);
   1127     return result;
   1128   }
   1129   *unsealed_data = StringFrom_TPM2B_SENSITIVE_DATA(out_data);
   1130   return TPM_RC_SUCCESS;
   1131 }
   1132 
   1133 TPM_RC TpmUtilityImpl::StartSession(HmacSession* session) {
   1134   TPM_RC result = session->StartUnboundSession(true  /* enable_encryption */);
   1135   if (result != TPM_RC_SUCCESS) {
   1136     LOG(ERROR) << "Error starting unbound session: " << GetErrorString(result);
   1137     return result;
   1138   }
   1139   session->SetEntityAuthorizationValue("");
   1140   return TPM_RC_SUCCESS;
   1141 }
   1142 
   1143 TPM_RC TpmUtilityImpl::GetPolicyDigestForPcrValue(int pcr_index,
   1144                                                   const std::string& pcr_value,
   1145                                                   std::string* policy_digest) {
   1146   CHECK(policy_digest);
   1147   scoped_ptr<PolicySession> session = factory_.GetTrialSession();
   1148   TPM_RC result = session->StartUnboundSession(false);
   1149   if (result != TPM_RC_SUCCESS) {
   1150     LOG(ERROR) << "Error starting unbound trial session: "
   1151                << GetErrorString(result);
   1152     return result;
   1153   }
   1154   std::string mutable_pcr_value;
   1155   if (pcr_value.empty()) {
   1156     result = ReadPCR(pcr_index, &mutable_pcr_value);
   1157     if (result != TPM_RC_SUCCESS) {
   1158       LOG(ERROR) << "Error reading pcr_value: " << GetErrorString(result);
   1159       return result;
   1160     }
   1161   } else {
   1162     mutable_pcr_value = pcr_value;
   1163   }
   1164   result = session->PolicyPCR(pcr_index, mutable_pcr_value);
   1165   if (result != TPM_RC_SUCCESS) {
   1166     LOG(ERROR) << "Error restricting policy to PCR value: "
   1167                << GetErrorString(result);
   1168     return result;
   1169   }
   1170   result = session->GetDigest(policy_digest);
   1171   if (result != TPM_RC_SUCCESS) {
   1172     LOG(ERROR) << "Error getting policy digest: " << GetErrorString(result);
   1173     return result;
   1174   }
   1175   return TPM_RC_SUCCESS;
   1176 }
   1177 
   1178 TPM_RC TpmUtilityImpl::DefineNVSpace(uint32_t index,
   1179                                      size_t num_bytes,
   1180                                      AuthorizationDelegate* delegate) {
   1181   TPM_RC result;
   1182   if (num_bytes > MAX_NV_INDEX_SIZE) {
   1183     result = SAPI_RC_BAD_SIZE;
   1184     LOG(ERROR) << "Cannot define non-volatile space of given size: "
   1185                << GetErrorString(result);
   1186     return result;
   1187   }
   1188   if (index > kMaxNVSpaceIndex) {
   1189     result = SAPI_RC_BAD_PARAMETER;
   1190     LOG(ERROR) << "Cannot define non-volatile space with the given index: "
   1191                << GetErrorString(result);
   1192     return result;
   1193   }
   1194   if (delegate == nullptr) {
   1195     result = SAPI_RC_INVALID_SESSIONS;
   1196     LOG(ERROR) << "This method needs a valid authorization delegate: "
   1197                << GetErrorString(result);
   1198     return result;
   1199   }
   1200   uint32_t nv_index = NV_INDEX_FIRST + index;
   1201   TPMS_NV_PUBLIC public_data;
   1202   public_data.nv_index = nv_index;
   1203   public_data.name_alg = TPM_ALG_SHA256;
   1204   // We define the following attributes for NVSpaces created:
   1205   // TPMA_NV_NO_DA: Dictionary attack does not trigger on authorization errors.
   1206   // TPMA_NV_OWNERWRITE: Owner authorization must be provided on write actions.
   1207   // TPMA_NV_WRITEDEFINE: NVSpace is write lockable, and lock persists across
   1208   //                      reboot.
   1209   // TPMA_NV_AUTHREAD: The index authValue (default: "") can be used to
   1210   //                   authorize read actions.
   1211   public_data.attributes = TPMA_NV_NO_DA |
   1212                            TPMA_NV_OWNERWRITE |
   1213                            TPMA_NV_WRITEDEFINE |
   1214                            TPMA_NV_AUTHREAD;
   1215   public_data.auth_policy = Make_TPM2B_DIGEST("");
   1216   public_data.data_size = num_bytes;
   1217   TPM2B_AUTH authorization = Make_TPM2B_DIGEST("");
   1218   TPM2B_NV_PUBLIC public_area = Make_TPM2B_NV_PUBLIC(public_data);
   1219   result = factory_.GetTpm()->NV_DefineSpaceSync(
   1220       TPM_RH_OWNER,
   1221       NameFromHandle(TPM_RH_OWNER),
   1222       authorization,
   1223       public_area,
   1224       delegate);
   1225   if (result != TPM_RC_SUCCESS) {
   1226     LOG(ERROR) << "Error defining non-volatile space: "
   1227                << GetErrorString(result);
   1228     return result;
   1229   }
   1230   nvram_public_area_map_[index] = public_data;
   1231   return TPM_RC_SUCCESS;
   1232 }
   1233 
   1234 TPM_RC TpmUtilityImpl::DestroyNVSpace(uint32_t index,
   1235                                       AuthorizationDelegate* delegate) {
   1236   TPM_RC result;
   1237   if (index > kMaxNVSpaceIndex) {
   1238     result = SAPI_RC_BAD_PARAMETER;
   1239     LOG(ERROR) << "Cannot undefine non-volatile space with the given index: "
   1240                << GetErrorString(result);
   1241     return result;
   1242   }
   1243   if (delegate == nullptr) {
   1244     result = SAPI_RC_INVALID_SESSIONS;
   1245     LOG(ERROR) << "This method needs a valid authorization delegate: "
   1246                << GetErrorString(result);
   1247     return result;
   1248   }
   1249   std::string nv_name;
   1250   result = GetNVSpaceName(index, &nv_name);
   1251   if (result != TPM_RC_SUCCESS) {
   1252     return result;
   1253   }
   1254   uint32_t nv_index = NV_INDEX_FIRST + index;
   1255   result = factory_.GetTpm()->NV_UndefineSpaceSync(
   1256       TPM_RH_OWNER,
   1257       NameFromHandle(TPM_RH_OWNER),
   1258       nv_index,
   1259       nv_name,
   1260       delegate);
   1261   if (result != TPM_RC_SUCCESS) {
   1262     LOG(ERROR) << "Error undefining non-volatile space: "
   1263                << GetErrorString(result);
   1264     return result;
   1265   }
   1266   nvram_public_area_map_.erase(index);
   1267   return TPM_RC_SUCCESS;
   1268 }
   1269 
   1270 TPM_RC TpmUtilityImpl::LockNVSpace(uint32_t index,
   1271                                    AuthorizationDelegate* delegate) {
   1272   TPM_RC result;
   1273   if (index > kMaxNVSpaceIndex) {
   1274     result = SAPI_RC_BAD_PARAMETER;
   1275     LOG(ERROR) << "Cannot lock non-volatile space with the given index: "
   1276                << GetErrorString(result);
   1277     return result;
   1278   }
   1279   if (delegate == nullptr) {
   1280     result = SAPI_RC_INVALID_SESSIONS;
   1281     LOG(ERROR) << "This method needs a valid authorization delegate: "
   1282                << GetErrorString(result);
   1283     return result;
   1284   }
   1285   std::string nv_name;
   1286   result = GetNVSpaceName(index, &nv_name);
   1287   if (result != TPM_RC_SUCCESS) {
   1288     return result;
   1289   }
   1290   uint32_t nv_index = NV_INDEX_FIRST + index;
   1291   result = factory_.GetTpm()->NV_WriteLockSync(TPM_RH_OWNER,
   1292                                                NameFromHandle(TPM_RH_OWNER),
   1293                                                nv_index,
   1294                                                nv_name,
   1295                                                delegate);
   1296   if (result != TPM_RC_SUCCESS) {
   1297     LOG(ERROR) << "Error locking non-volatile spaces: "
   1298                << GetErrorString(result);
   1299     return result;
   1300   }
   1301   auto it = nvram_public_area_map_.find(index);
   1302   if (it != nvram_public_area_map_.end()) {
   1303     it->second.attributes |= TPMA_NV_WRITELOCKED;
   1304   }
   1305   return TPM_RC_SUCCESS;
   1306 }
   1307 
   1308 TPM_RC TpmUtilityImpl::WriteNVSpace(uint32_t index,
   1309                                     uint32_t offset,
   1310                                     const std::string& nvram_data,
   1311                                     AuthorizationDelegate* delegate) {
   1312   TPM_RC result;
   1313   if (nvram_data.size() > MAX_NV_BUFFER_SIZE) {
   1314     result = SAPI_RC_BAD_SIZE;
   1315     LOG(ERROR) << "Insufficient buffer for non-volatile write: "
   1316                << GetErrorString(result);
   1317     return result;
   1318   }
   1319   if (index > kMaxNVSpaceIndex) {
   1320     result = SAPI_RC_BAD_PARAMETER;
   1321     LOG(ERROR) << "Cannot write to non-volatile space with the given index: "
   1322                << GetErrorString(result);
   1323     return result;
   1324   }
   1325   if (delegate == nullptr) {
   1326     result = SAPI_RC_INVALID_SESSIONS;
   1327     LOG(ERROR) << "This method needs a valid authorization delegate: "
   1328                << GetErrorString(result);
   1329     return result;
   1330   }
   1331   std::string nv_name;
   1332   result = GetNVSpaceName(index, &nv_name);
   1333   if (result != TPM_RC_SUCCESS) {
   1334     return result;
   1335   }
   1336   uint32_t nv_index = NV_INDEX_FIRST + index;
   1337   result = factory_.GetTpm()->NV_WriteSync(TPM_RH_OWNER,
   1338                                            NameFromHandle(TPM_RH_OWNER),
   1339                                            nv_index,
   1340                                            nv_name,
   1341                                            Make_TPM2B_MAX_NV_BUFFER(nvram_data),
   1342                                            offset,
   1343                                            delegate);
   1344   if (result != TPM_RC_SUCCESS) {
   1345     LOG(ERROR) << "Error writing to non-volatile space: "
   1346                << GetErrorString(result);
   1347     return result;
   1348   }
   1349   auto it = nvram_public_area_map_.find(index);
   1350   if (it != nvram_public_area_map_.end()) {
   1351     it->second.attributes |= TPMA_NV_WRITTEN;
   1352   }
   1353   return TPM_RC_SUCCESS;
   1354 }
   1355 
   1356 TPM_RC TpmUtilityImpl::ReadNVSpace(uint32_t index,
   1357                                    uint32_t offset,
   1358                                    size_t num_bytes,
   1359                                    std::string* nvram_data,
   1360                                    AuthorizationDelegate* delegate) {
   1361   TPM_RC result;
   1362   if (num_bytes > MAX_NV_BUFFER_SIZE) {
   1363     result = SAPI_RC_BAD_SIZE;
   1364     LOG(ERROR) << "Insufficient buffer for non-volatile read: "
   1365                << GetErrorString(result);
   1366     return result;
   1367   }
   1368   if (index > kMaxNVSpaceIndex) {
   1369     result = SAPI_RC_BAD_PARAMETER;
   1370     LOG(ERROR) << "Cannot read from non-volatile space with the given index: "
   1371                << GetErrorString(result);
   1372     return result;
   1373   }
   1374   if (delegate == nullptr) {
   1375     result = SAPI_RC_INVALID_SESSIONS;
   1376     LOG(ERROR) << "This method needs a valid authorization delegate: "
   1377                << GetErrorString(result);
   1378     return result;
   1379   }
   1380   std::string nv_name;
   1381   result = GetNVSpaceName(index, &nv_name);
   1382   if (result != TPM_RC_SUCCESS) {
   1383     return result;
   1384   }
   1385   uint32_t nv_index = NV_INDEX_FIRST + index;
   1386   TPM2B_MAX_NV_BUFFER data_buffer;
   1387   data_buffer.size = 0;
   1388   result = factory_.GetTpm()->NV_ReadSync(nv_index,
   1389                                           nv_name,
   1390                                           nv_index,
   1391                                           nv_name,
   1392                                           num_bytes,
   1393                                           offset,
   1394                                           &data_buffer,
   1395                                           delegate);
   1396   if (result != TPM_RC_SUCCESS) {
   1397     LOG(ERROR) << "Error reading from non-volatile space: "
   1398                << GetErrorString(result);
   1399     return result;
   1400   }
   1401   nvram_data->assign(StringFrom_TPM2B_MAX_NV_BUFFER(data_buffer));
   1402   return TPM_RC_SUCCESS;
   1403 }
   1404 
   1405 TPM_RC TpmUtilityImpl::GetNVSpaceName(uint32_t index, std::string* name) {
   1406   TPM_RC result;
   1407   if (index > kMaxNVSpaceIndex) {
   1408     result = SAPI_RC_BAD_PARAMETER;
   1409     LOG(ERROR) << "Cannot read from non-volatile space with the given index: "
   1410                << GetErrorString(result);
   1411     return result;
   1412   }
   1413   TPMS_NV_PUBLIC nv_public_data;
   1414   result = GetNVSpacePublicArea(index, &nv_public_data);
   1415   if (result != TPM_RC_SUCCESS) {
   1416     return result;
   1417   }
   1418   result = ComputeNVSpaceName(nv_public_data, name);
   1419   if (result != TPM_RC_SUCCESS) {
   1420     return result;
   1421   }
   1422   return TPM_RC_SUCCESS;
   1423 }
   1424 
   1425 TPM_RC TpmUtilityImpl::GetNVSpacePublicArea(uint32_t index,
   1426                                             TPMS_NV_PUBLIC* public_data) {
   1427   TPM_RC result;
   1428   if (index > kMaxNVSpaceIndex) {
   1429     result = SAPI_RC_BAD_PARAMETER;
   1430     LOG(ERROR) << "Cannot read from non-volatile space with the given index: "
   1431                << GetErrorString(result);
   1432     return result;
   1433   }
   1434   auto it = nvram_public_area_map_.find(index);
   1435   if (it != nvram_public_area_map_.end()) {
   1436     *public_data = it->second;
   1437     return TPM_RC_SUCCESS;
   1438   }
   1439   TPM2B_NAME nvram_name;
   1440   TPM2B_NV_PUBLIC public_area;
   1441   public_area.nv_public.nv_index = 0;
   1442   uint32_t nv_index = NV_INDEX_FIRST + index;
   1443   result = factory_.GetTpm()->NV_ReadPublicSync(nv_index,
   1444                                                 "",
   1445                                                 &public_area,
   1446                                                 &nvram_name,
   1447                                                 nullptr);
   1448   if (result != TPM_RC_SUCCESS) {
   1449     LOG(ERROR) << "Error reading non-volatile space public information: "
   1450                << GetErrorString(result);
   1451     return result;
   1452   }
   1453   *public_data = public_area.nv_public;
   1454   nvram_public_area_map_[index] = public_area.nv_public;
   1455   return TPM_RC_SUCCESS;
   1456 }
   1457 
   1458 TPM_RC TpmUtilityImpl::SetKnownOwnerPassword(
   1459     const std::string& known_owner_password) {
   1460   scoped_ptr<TpmState> tpm_state(factory_.GetTpmState());
   1461   TPM_RC result = tpm_state->Initialize();
   1462   if (result) {
   1463     LOG(ERROR) << __func__ << ": " << GetErrorString(result);
   1464     return result;
   1465   }
   1466   scoped_ptr<AuthorizationDelegate> delegate =
   1467       factory_.GetPasswordAuthorization("");
   1468   if (tpm_state->IsOwnerPasswordSet()) {
   1469     LOG(INFO) << "Owner password is already set. "
   1470               << "This is normal if ownership is already taken.";
   1471     return TPM_RC_SUCCESS;
   1472   }
   1473   result = SetHierarchyAuthorization(TPM_RH_OWNER,
   1474                                      known_owner_password,
   1475                                      delegate.get());
   1476   if (result) {
   1477     LOG(ERROR) << "Error setting storage hierarchy authorization "
   1478                << "to its default value: " << GetErrorString(result);
   1479     return result;
   1480   }
   1481   return TPM_RC_SUCCESS;
   1482 }
   1483 
   1484 TPM_RC TpmUtilityImpl::CreateStorageRootKeys(
   1485     const std::string& owner_password) {
   1486   TPM_RC result = TPM_RC_SUCCESS;
   1487   scoped_ptr<TpmState>  tpm_state(factory_.GetTpmState());
   1488   result = tpm_state->Initialize();
   1489   if (result) {
   1490     LOG(ERROR) << __func__ << ": " << GetErrorString(result);
   1491     return result;
   1492   }
   1493   Tpm* tpm = factory_.GetTpm();
   1494   TPML_PCR_SELECTION creation_pcrs;
   1495   creation_pcrs.count = 0;
   1496   TPMS_SENSITIVE_CREATE sensitive;
   1497   sensitive.user_auth = Make_TPM2B_DIGEST("");
   1498   sensitive.data = Make_TPM2B_SENSITIVE_DATA("");
   1499   TPM_HANDLE object_handle;
   1500   TPM2B_CREATION_DATA creation_data;
   1501   TPM2B_DIGEST creation_digest;
   1502   TPMT_TK_CREATION creation_ticket;
   1503   TPM2B_NAME object_name;
   1504   object_name.size = 0;
   1505   scoped_ptr<AuthorizationDelegate> delegate =
   1506       factory_.GetPasswordAuthorization(owner_password);
   1507   if (tpm_state->IsRSASupported()) {
   1508     bool exists = false;
   1509     result = DoesPersistentKeyExist(kRSAStorageRootKey, &exists);
   1510     if (result) {
   1511       return result;
   1512     }
   1513     if (!exists) {
   1514       TPMT_PUBLIC public_area = CreateDefaultPublicArea(TPM_ALG_RSA);
   1515       public_area.object_attributes |=
   1516           (kSensitiveDataOrigin | kUserWithAuth | kNoDA |
   1517            kRestricted | kDecrypt);
   1518       public_area.parameters.rsa_detail.symmetric.algorithm = TPM_ALG_AES;
   1519       public_area.parameters.rsa_detail.symmetric.key_bits.aes = 128;
   1520       public_area.parameters.rsa_detail.symmetric.mode.aes = TPM_ALG_CFB;
   1521       TPM2B_PUBLIC rsa_public_area = Make_TPM2B_PUBLIC(public_area);
   1522       result = tpm->CreatePrimarySync(TPM_RH_OWNER,
   1523                                       NameFromHandle(TPM_RH_OWNER),
   1524                                       Make_TPM2B_SENSITIVE_CREATE(sensitive),
   1525                                       rsa_public_area,
   1526                                       Make_TPM2B_DATA(""),
   1527                                       creation_pcrs,
   1528                                       &object_handle,
   1529                                       &rsa_public_area,
   1530                                       &creation_data,
   1531                                       &creation_digest,
   1532                                       &creation_ticket,
   1533                                       &object_name,
   1534                                       delegate.get());
   1535       if (result) {
   1536         LOG(ERROR) << __func__ << ": " << GetErrorString(result);
   1537         return result;
   1538       }
   1539       ScopedKeyHandle rsa_key(factory_, object_handle);
   1540       // This will make the key persistent.
   1541       result = tpm->EvictControlSync(TPM_RH_OWNER,
   1542                                      NameFromHandle(TPM_RH_OWNER),
   1543                                      object_handle,
   1544                                      StringFrom_TPM2B_NAME(object_name),
   1545                                      kRSAStorageRootKey,
   1546                                      delegate.get());
   1547       if (result != TPM_RC_SUCCESS) {
   1548         LOG(ERROR) << __func__ << ": " << GetErrorString(result);
   1549         return result;
   1550       }
   1551       LOG(INFO) << "Created RSA SRK.";
   1552     } else {
   1553       LOG(INFO) << "Skip RSA SRK because it already exists.";
   1554     }
   1555   } else {
   1556     LOG(INFO) << "Skip RSA SRK because RSA is not supported.";
   1557   }
   1558 
   1559   // Do it again for ECC.
   1560   if (tpm_state->IsRSASupported()) {
   1561     bool exists = false;
   1562     result = DoesPersistentKeyExist(kECCStorageRootKey, &exists);
   1563     if (result) {
   1564       return result;
   1565     }
   1566     if (!exists) {
   1567       TPMT_PUBLIC public_area = CreateDefaultPublicArea(TPM_ALG_ECC);
   1568       public_area.object_attributes |=
   1569           (kSensitiveDataOrigin | kUserWithAuth | kNoDA |
   1570            kRestricted | kDecrypt);
   1571       public_area.parameters.ecc_detail.symmetric.algorithm = TPM_ALG_AES;
   1572       public_area.parameters.ecc_detail.symmetric.key_bits.aes = 128;
   1573       public_area.parameters.ecc_detail.symmetric.mode.aes = TPM_ALG_CFB;
   1574       TPM2B_PUBLIC ecc_public_area = Make_TPM2B_PUBLIC(public_area);
   1575       result = tpm->CreatePrimarySync(TPM_RH_OWNER,
   1576                                       NameFromHandle(TPM_RH_OWNER),
   1577                                       Make_TPM2B_SENSITIVE_CREATE(sensitive),
   1578                                       ecc_public_area,
   1579                                       Make_TPM2B_DATA(""),
   1580                                       creation_pcrs,
   1581                                       &object_handle,
   1582                                       &ecc_public_area,
   1583                                       &creation_data,
   1584                                       &creation_digest,
   1585                                       &creation_ticket,
   1586                                       &object_name,
   1587                                       delegate.get());
   1588       if (result) {
   1589         LOG(ERROR) << __func__ << ": " << GetErrorString(result);
   1590         return result;
   1591       }
   1592       ScopedKeyHandle ecc_key(factory_, object_handle);
   1593       // This will make the key persistent.
   1594       result = tpm->EvictControlSync(TPM_RH_OWNER,
   1595                                      NameFromHandle(TPM_RH_OWNER),
   1596                                      object_handle,
   1597                                      StringFrom_TPM2B_NAME(object_name),
   1598                                      kECCStorageRootKey,
   1599                                      delegate.get());
   1600       if (result != TPM_RC_SUCCESS) {
   1601         LOG(ERROR) << __func__ << ": " << GetErrorString(result);
   1602         return result;
   1603       }
   1604       LOG(INFO) << "Created ECC SRK.";
   1605     } else {
   1606       LOG(INFO) << "Skip ECC SRK because it already exists.";
   1607     }
   1608   } else {
   1609     LOG(INFO) << "Skip ECC SRK because ECC is not supported.";
   1610   }
   1611   return TPM_RC_SUCCESS;
   1612 }
   1613 
   1614 TPM_RC TpmUtilityImpl::CreateSaltingKey(const std::string& owner_password) {
   1615   bool exists = false;
   1616   TPM_RC result = DoesPersistentKeyExist(kSaltingKey, &exists);
   1617   if (result != TPM_RC_SUCCESS) {
   1618     return result;
   1619   }
   1620   if (exists) {
   1621     LOG(INFO) << "Salting key already exists.";
   1622     return TPM_RC_SUCCESS;
   1623   }
   1624   std::string parent_name;
   1625   result = GetKeyName(kRSAStorageRootKey, &parent_name);
   1626   if (result != TPM_RC_SUCCESS) {
   1627     LOG(ERROR) << "Error getting Key name for RSA-SRK: "
   1628                << GetErrorString(result);
   1629     return result;
   1630   }
   1631   TPMT_PUBLIC public_area = CreateDefaultPublicArea(TPM_ALG_RSA);
   1632   public_area.name_alg = TPM_ALG_SHA256;
   1633   public_area.object_attributes |=
   1634       kSensitiveDataOrigin | kUserWithAuth | kNoDA | kDecrypt;
   1635   TPML_PCR_SELECTION creation_pcrs;
   1636   creation_pcrs.count = 0;
   1637   TPMS_SENSITIVE_CREATE sensitive;
   1638   sensitive.user_auth = Make_TPM2B_DIGEST("");
   1639   sensitive.data = Make_TPM2B_SENSITIVE_DATA("");
   1640   TPM2B_SENSITIVE_CREATE sensitive_create = Make_TPM2B_SENSITIVE_CREATE(
   1641       sensitive);
   1642   TPM2B_DATA outside_info = Make_TPM2B_DATA("");
   1643 
   1644   TPM2B_PRIVATE out_private;
   1645   out_private.size = 0;
   1646   TPM2B_PUBLIC out_public;
   1647   out_public.size = 0;
   1648   TPM2B_CREATION_DATA creation_data;
   1649   TPM2B_DIGEST creation_hash;
   1650   TPMT_TK_CREATION creation_ticket;
   1651   // TODO(usanghi): MITM vulnerability with SaltingKey creation.
   1652   // Currently we cannot verify the key returned by the TPM.
   1653   // crbug.com/442331
   1654   scoped_ptr<AuthorizationDelegate> delegate =
   1655       factory_.GetPasswordAuthorization("");
   1656   result = factory_.GetTpm()->CreateSync(kRSAStorageRootKey,
   1657                                          parent_name,
   1658                                          sensitive_create,
   1659                                          Make_TPM2B_PUBLIC(public_area),
   1660                                          outside_info,
   1661                                          creation_pcrs,
   1662                                          &out_private,
   1663                                          &out_public,
   1664                                          &creation_data,
   1665                                          &creation_hash,
   1666                                          &creation_ticket,
   1667                                          delegate.get());
   1668   if (result != TPM_RC_SUCCESS) {
   1669     LOG(ERROR) << "Error creating salting key: " << GetErrorString(result);
   1670     return result;
   1671   }
   1672   TPM2B_NAME key_name;
   1673   key_name.size = 0;
   1674   TPM_HANDLE key_handle;
   1675   result = factory_.GetTpm()->LoadSync(kRSAStorageRootKey,
   1676                                        parent_name,
   1677                                        out_private,
   1678                                        out_public,
   1679                                        &key_handle,
   1680                                        &key_name,
   1681                                        delegate.get());
   1682   if (result != TPM_RC_SUCCESS) {
   1683     LOG(ERROR) << "Error loading salting key: " << GetErrorString(result);
   1684     return result;
   1685   }
   1686   ScopedKeyHandle key(factory_, key_handle);
   1687   scoped_ptr<AuthorizationDelegate> owner_delegate =
   1688       factory_.GetPasswordAuthorization(owner_password);
   1689   result = factory_.GetTpm()->EvictControlSync(TPM_RH_OWNER,
   1690                                                NameFromHandle(TPM_RH_OWNER),
   1691                                                key_handle,
   1692                                                StringFrom_TPM2B_NAME(key_name),
   1693                                                kSaltingKey,
   1694                                                owner_delegate.get());
   1695   if (result != TPM_RC_SUCCESS) {
   1696     LOG(ERROR) << __func__ << ": " << GetErrorString(result);
   1697     return result;
   1698   }
   1699   return TPM_RC_SUCCESS;
   1700 }
   1701 
   1702 TPMT_PUBLIC TpmUtilityImpl::CreateDefaultPublicArea(TPM_ALG_ID key_alg) {
   1703   TPMT_PUBLIC public_area;
   1704   public_area.name_alg = TPM_ALG_SHA256;
   1705   public_area.auth_policy = Make_TPM2B_DIGEST("");
   1706   public_area.object_attributes = kFixedTPM | kFixedParent;
   1707   if (key_alg == TPM_ALG_RSA) {
   1708     public_area.type = TPM_ALG_RSA;
   1709     public_area.parameters.rsa_detail.scheme.scheme = TPM_ALG_NULL;
   1710     public_area.parameters.rsa_detail.symmetric.algorithm = TPM_ALG_NULL;
   1711     public_area.parameters.rsa_detail.key_bits = 2048;
   1712     public_area.parameters.rsa_detail.exponent = 0;
   1713     public_area.unique.rsa = Make_TPM2B_PUBLIC_KEY_RSA("");
   1714   } else if (key_alg == TPM_ALG_ECC) {
   1715     public_area.type = TPM_ALG_ECC;
   1716     public_area.parameters.ecc_detail.curve_id = TPM_ECC_NIST_P256;
   1717     public_area.parameters.ecc_detail.kdf.scheme = TPM_ALG_NULL;
   1718     public_area.unique.ecc.x = Make_TPM2B_ECC_PARAMETER("");
   1719     public_area.unique.ecc.y = Make_TPM2B_ECC_PARAMETER("");
   1720   } else if (key_alg == TPM_ALG_KEYEDHASH) {
   1721     public_area.type = TPM_ALG_KEYEDHASH;
   1722     public_area.parameters.keyed_hash_detail.scheme.scheme = TPM_ALG_NULL;
   1723   } else {
   1724     LOG(WARNING) << "Unrecognized key_type. Not filling parameters.";
   1725   }
   1726   return public_area;
   1727 }
   1728 
   1729 TPM_RC TpmUtilityImpl::SetHierarchyAuthorization(
   1730     TPMI_RH_HIERARCHY_AUTH hierarchy,
   1731     const std::string& password,
   1732     AuthorizationDelegate* authorization) {
   1733   if (password.size() > kMaxPasswordLength) {
   1734     LOG(ERROR) << "Hierarchy passwords can be at most " << kMaxPasswordLength
   1735                << " bytes. Current password length is: " << password.size();
   1736     return SAPI_RC_BAD_SIZE;
   1737   }
   1738   return factory_.GetTpm()->HierarchyChangeAuthSync(
   1739       hierarchy,
   1740       NameFromHandle(hierarchy),
   1741       Make_TPM2B_DIGEST(password),
   1742       authorization);
   1743 }
   1744 
   1745 TPM_RC TpmUtilityImpl::DisablePlatformHierarchy(
   1746     AuthorizationDelegate* authorization) {
   1747   return factory_.GetTpm()->HierarchyControlSync(
   1748       TPM_RH_PLATFORM,  // The authorizing entity.
   1749       NameFromHandle(TPM_RH_PLATFORM),
   1750       TPM_RH_PLATFORM,  // The target hierarchy.
   1751       0,  // Disable.
   1752       authorization);
   1753 }
   1754 
   1755 TPM_RC TpmUtilityImpl::ComputeKeyName(const TPMT_PUBLIC& public_area,
   1756                                       std::string* object_name) {
   1757   CHECK(object_name);
   1758   if (public_area.type == TPM_ALG_ERROR) {
   1759     // We do not compute a name for empty public area.
   1760     object_name->clear();
   1761     return TPM_RC_SUCCESS;
   1762   }
   1763   std::string serialized_public_area;
   1764   TPM_RC result = Serialize_TPMT_PUBLIC(public_area, &serialized_public_area);
   1765   if (result != TPM_RC_SUCCESS) {
   1766     LOG(ERROR) << "Error serializing public area: " << GetErrorString(result);
   1767     return result;
   1768   }
   1769   std::string serialized_name_alg;
   1770   result = Serialize_TPM_ALG_ID(TPM_ALG_SHA256, &serialized_name_alg);
   1771   if (result != TPM_RC_SUCCESS) {
   1772     LOG(ERROR) << "Error serializing public area: " << GetErrorString(result);
   1773     return result;
   1774   }
   1775   object_name->assign(serialized_name_alg +
   1776                       crypto::SHA256HashString(serialized_public_area));
   1777   return TPM_RC_SUCCESS;
   1778 }
   1779 
   1780 TPM_RC TpmUtilityImpl::ComputeNVSpaceName(const TPMS_NV_PUBLIC& nv_public_area,
   1781                                           std::string* nv_name) {
   1782   CHECK(nv_name);
   1783   if ((nv_public_area.nv_index & NV_INDEX_FIRST) == 0) {
   1784     // If the index is not an nvram index, we do not compute a name.
   1785     nv_name->clear();
   1786     return TPM_RC_SUCCESS;
   1787   }
   1788   std::string serialized_public_area;
   1789   TPM_RC result = Serialize_TPMS_NV_PUBLIC(nv_public_area,
   1790                                            &serialized_public_area);
   1791   if (result != TPM_RC_SUCCESS) {
   1792     LOG(ERROR) << "Error serializing public area: " << GetErrorString(result);
   1793     return result;
   1794   }
   1795   std::string serialized_name_alg;
   1796   result = Serialize_TPM_ALG_ID(TPM_ALG_SHA256, &serialized_name_alg);
   1797   if (result != TPM_RC_SUCCESS) {
   1798     LOG(ERROR) << "Error serializing public area: " << GetErrorString(result);
   1799     return result;
   1800   }
   1801   nv_name->assign(serialized_name_alg +
   1802                   crypto::SHA256HashString(serialized_public_area));
   1803   return TPM_RC_SUCCESS;
   1804 }
   1805 
   1806 TPM_RC TpmUtilityImpl::EncryptPrivateData(const TPMT_SENSITIVE& sensitive_area,
   1807                                           const TPMT_PUBLIC& public_area,
   1808                                           TPM2B_PRIVATE* encrypted_private_data,
   1809                                           TPM2B_DATA* encryption_key) {
   1810   TPM2B_SENSITIVE sensitive_data = Make_TPM2B_SENSITIVE(sensitive_area);
   1811   std::string serialized_sensitive_data;
   1812   TPM_RC result = Serialize_TPM2B_SENSITIVE(sensitive_data,
   1813                                             &serialized_sensitive_data);
   1814   if (result != TPM_RC_SUCCESS) {
   1815     LOG(ERROR) << "Error serializing sensitive data: "
   1816                << GetErrorString(result);
   1817     return result;
   1818   }
   1819   std::string object_name;
   1820   result = ComputeKeyName(public_area, &object_name);
   1821   if (result != TPM_RC_SUCCESS) {
   1822     LOG(ERROR) << "Error computing object name: " << GetErrorString(result);
   1823     return result;
   1824   }
   1825   TPM2B_DIGEST inner_integrity = Make_TPM2B_DIGEST(crypto::SHA256HashString(
   1826       serialized_sensitive_data + object_name));
   1827   std::string serialized_inner_integrity;
   1828   result = Serialize_TPM2B_DIGEST(inner_integrity, &serialized_inner_integrity);
   1829   if (result != TPM_RC_SUCCESS) {
   1830     LOG(ERROR) << "Error serializing inner integrity: "
   1831                << GetErrorString(result);
   1832     return result;
   1833   }
   1834   std::string unencrypted_private_data = serialized_inner_integrity +
   1835                                          serialized_sensitive_data;
   1836   AES_KEY key;
   1837   AES_set_encrypt_key(encryption_key->buffer, kAesKeySize * 8, &key);
   1838   std::string private_data_string(unencrypted_private_data.size(), 0);
   1839   int iv_in = 0;
   1840   unsigned char iv[MAX_AES_BLOCK_SIZE_BYTES] = {0};
   1841   AES_cfb128_encrypt(
   1842     reinterpret_cast<const unsigned char*>(unencrypted_private_data.data()),
   1843     reinterpret_cast<unsigned char*>(string_as_array(&private_data_string)),
   1844     unencrypted_private_data.size(), &key, iv, &iv_in, AES_ENCRYPT);
   1845   *encrypted_private_data = Make_TPM2B_PRIVATE(private_data_string);
   1846   if (result != TPM_RC_SUCCESS) {
   1847     LOG(ERROR) << "Error making private area: "
   1848                << GetErrorString(result);
   1849     return result;
   1850   }
   1851   return TPM_RC_SUCCESS;
   1852 }
   1853 
   1854 TPM_RC TpmUtilityImpl::DoesPersistentKeyExist(TPMI_DH_PERSISTENT key_handle,
   1855                                               bool* exists) {
   1856   TPM_RC result;
   1857   TPMI_YES_NO more_data = YES;
   1858   TPMS_CAPABILITY_DATA capability_data;
   1859   result = factory_.GetTpm()->GetCapabilitySync(
   1860       TPM_CAP_HANDLES, key_handle, 1 /*property_count*/, &more_data,
   1861       &capability_data, nullptr /*authorization_delegate*/);
   1862   if (result != TPM_RC_SUCCESS) {
   1863     LOG(ERROR) << __func__
   1864                << ": Error querying handles: " << GetErrorString(result);
   1865     return result;
   1866   }
   1867   TPML_HANDLE& handles = capability_data.data.handles;
   1868   *exists = (handles.count == 1 && handles.handle[0] == key_handle);
   1869   return TPM_RC_SUCCESS;
   1870 }
   1871 
   1872 }  // namespace trunks
   1873