• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
Tpm2InitializerImpl(LocalDataStore * local_data_store,TpmStatus * tpm_status)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 
Tpm2InitializerImpl(trunks::TrunksFactory * factory,OpensslCryptoUtil * openssl_util,LocalDataStore * local_data_store,TpmStatus * tpm_status)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 
InitializeTpm()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 
SeedTpmRng()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 
GetTpmRandomData(size_t num_bytes,std::string * random_data)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