Home | History | Annotate | Download | only in server
      1 //
      2 // Copyright (C) 2015 The Android Open Source Project
      3 //
      4 // Licensed under the Apache License, Version 2.0 (the "License");
      5 // you may not use this file except in compliance with the License.
      6 // You may obtain a copy of the License at
      7 //
      8 //      http://www.apache.org/licenses/LICENSE-2.0
      9 //
     10 // Unless required by applicable law or agreed to in writing, software
     11 // distributed under the License is distributed on an "AS IS" BASIS,
     12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 // See the License for the specific language governing permissions and
     14 // limitations under the License.
     15 //
     16 
     17 #include "tpm_manager/server/tpm2_initializer_impl.h"
     18 
     19 #include <string>
     20 
     21 #include <base/logging.h>
     22 #include <trunks/tpm_utility.h>
     23 #include <trunks/trunks_factory_impl.h>
     24 
     25 #include "tpm_manager/common/local_data.pb.h"
     26 #include "tpm_manager/common/tpm_manager_constants.h"
     27 #include "tpm_manager/server/openssl_crypto_util_impl.h"
     28 
     29 namespace {
     30 const size_t kDefaultPasswordSize = 20;
     31 }  // namespace
     32 
     33 namespace tpm_manager {
     34 
     35 Tpm2InitializerImpl::Tpm2InitializerImpl(LocalDataStore* local_data_store,
     36                                          TpmStatus* tpm_status)
     37     : trunks_factory_(new trunks::TrunksFactoryImpl()),
     38       openssl_util_(new OpensslCryptoUtilImpl()),
     39       local_data_store_(local_data_store),
     40       tpm_status_(tpm_status) {}
     41 
     42 Tpm2InitializerImpl::Tpm2InitializerImpl(trunks::TrunksFactory* factory,
     43                                          OpensslCryptoUtil* openssl_util,
     44                                          LocalDataStore* local_data_store,
     45                                          TpmStatus* tpm_status)
     46     : trunks_factory_(factory),
     47       openssl_util_(openssl_util),
     48       local_data_store_(local_data_store),
     49       tpm_status_(tpm_status) {}
     50 
     51 bool Tpm2InitializerImpl::InitializeTpm() {
     52   if (!SeedTpmRng()) {
     53     return false;
     54   }
     55   if (tpm_status_->IsTpmOwned()) {
     56     // Tpm is already owned, so we do not need to do anything.
     57     VLOG(1) << "Tpm already owned.";
     58     return true;
     59   }
     60   // First we read the local data. If we did not finish removing owner
     61   // dependencies or if TakeOwnership failed, we want to retake ownership
     62   // with the same passwords.
     63   LocalData local_data;
     64   if (!local_data_store_->Read(&local_data)) {
     65     LOG(ERROR) << "Error reading local data.";
     66     return false;
     67   }
     68   std::string owner_password;
     69   std::string endorsement_password;
     70   std::string lockout_password;
     71   // If there are valid owner dependencies, we need to reuse the old passwords.
     72   if (local_data.owner_dependency_size() > 0) {
     73     owner_password.assign(local_data.owner_password());
     74     endorsement_password.assign(local_data.endorsement_password());
     75     lockout_password.assign(local_data.lockout_password());
     76   } else {
     77     if (!GetTpmRandomData(kDefaultPasswordSize, &owner_password)) {
     78       LOG(ERROR) << "Error generating a random owner password.";
     79       return false;
     80     }
     81     if (!GetTpmRandomData(kDefaultPasswordSize, &endorsement_password)) {
     82       LOG(ERROR) << "Error generating a random endorsement password.";
     83       return false;
     84     }
     85     if (!GetTpmRandomData(kDefaultPasswordSize, &lockout_password)) {
     86       LOG(ERROR) << "Error generating a random lockout password.";
     87       return false;
     88     }
     89   }
     90   // We write the passwords to disk, in case there is an error while taking
     91   // ownership.
     92   local_data.clear_owner_dependency();
     93   for (auto dependency: kInitialTpmOwnerDependencies) {
     94     local_data.add_owner_dependency(dependency);
     95   }
     96   local_data.set_owner_password(owner_password);
     97   local_data.set_endorsement_password(endorsement_password);
     98   local_data.set_lockout_password(lockout_password);
     99   if (!local_data_store_->Write(local_data)) {
    100     LOG(ERROR) << "Error saving local data.";
    101     return false;
    102   }
    103   trunks::TPM_RC result = trunks_factory_->GetTpmUtility()->TakeOwnership(
    104       owner_password, endorsement_password, lockout_password);
    105   if (result != trunks::TPM_RC_SUCCESS) {
    106     LOG(ERROR) << "Error taking ownership of TPM2.0";
    107     return false;
    108   }
    109   return true;
    110 }
    111 
    112 bool Tpm2InitializerImpl::SeedTpmRng() {
    113   std::string random_bytes;
    114   if (!openssl_util_->GetRandomBytes(kDefaultPasswordSize, &random_bytes)) {
    115     return false;
    116   }
    117   trunks::TPM_RC result = trunks_factory_->GetTpmUtility()->StirRandom(
    118       random_bytes, nullptr  /* No Authorization */);
    119   if (result != trunks::TPM_RC_SUCCESS) {
    120     return false;
    121   }
    122   return true;
    123 }
    124 
    125 bool Tpm2InitializerImpl::GetTpmRandomData(size_t num_bytes,
    126                                            std::string* random_data) {
    127   trunks::TPM_RC result = trunks_factory_->GetTpmUtility()->GenerateRandom(
    128       num_bytes, nullptr  /* No Authorization */, random_data);
    129   if (result != trunks::TPM_RC_SUCCESS) {
    130     return false;
    131   }
    132   return true;
    133 }
    134 
    135 }  // namespace tpm_manager
    136