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