• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_state_impl.h"
18 
19 #include <base/logging.h>
20 
21 #include "trunks/error_codes.h"
22 #include "trunks/tpm_generated.h"
23 #include "trunks/trunks_factory.h"
24 
25 namespace {
26 
27 // From definition of TPMA_PERMANENT.
28 const trunks::TPMA_PERMANENT kOwnerAuthSetMask = 1U;
29 const trunks::TPMA_PERMANENT kEndorsementAuthSetMask = 1U << 1;
30 const trunks::TPMA_PERMANENT kLockoutAuthSetMask = 1U << 2;
31 const trunks::TPMA_PERMANENT kInLockoutMask = 1U << 9;
32 
33 // From definition of TPMA_STARTUP_CLEAR.
34 const trunks::TPMA_STARTUP_CLEAR kPlatformHierarchyMask = 1U;
35 const trunks::TPMA_STARTUP_CLEAR kStorageHierarchyMask = 1U << 1;
36 const trunks::TPMA_STARTUP_CLEAR kEndorsementHierarchyMask = 1U << 2;
37 const trunks::TPMA_STARTUP_CLEAR kOrderlyShutdownMask = 1U << 31;
38 
39 // From definition of TPMA_ALGORITHM
40 const trunks::TPMA_ALGORITHM kAsymmetricAlgMask = 1U;
41 
42 }  // namespace
43 
44 namespace trunks {
45 
TpmStateImpl(const TrunksFactory & factory)46 TpmStateImpl::TpmStateImpl(const TrunksFactory& factory)
47     : factory_(factory),
48       initialized_(false),
49       permanent_flags_(0),
50       startup_clear_flags_(0),
51       rsa_flags_(0),
52       ecc_flags_(0) {
53 }
54 
~TpmStateImpl()55 TpmStateImpl::~TpmStateImpl() {}
56 
Initialize()57 TPM_RC TpmStateImpl::Initialize() {
58   TPM_RC result = GetTpmProperty(TPM_PT_PERMANENT, &permanent_flags_);
59   if (result != TPM_RC_SUCCESS) {
60     LOG(ERROR) << "Error getting permanent flags: " << GetErrorString(result);
61     return result;
62   }
63   result = GetTpmProperty(TPM_PT_STARTUP_CLEAR, &startup_clear_flags_);
64   if (result != TPM_RC_SUCCESS) {
65     LOG(ERROR) << "Error getting startup flags: " << GetErrorString(result);
66     return result;
67   }
68   result = GetTpmProperty(TPM_PT_LOCKOUT_COUNTER, &lockout_counter_);
69   if (result != TPM_RC_SUCCESS) {
70     LOG(ERROR) << "Error getting lockout counter: " << GetErrorString(result);
71     return result;
72   }
73   result = GetTpmProperty(TPM_PT_MAX_AUTH_FAIL, &lockout_threshold_);
74   if (result != TPM_RC_SUCCESS) {
75     LOG(ERROR) << "Error getting lockout threshold: " << GetErrorString(result);
76     return result;
77   }
78   result = GetTpmProperty(TPM_PT_LOCKOUT_INTERVAL, &lockout_interval_);
79   if (result != TPM_RC_SUCCESS) {
80     LOG(ERROR) << "Error getting lockout interval: " << GetErrorString(result);
81     return result;
82   }
83   result = GetTpmProperty(TPM_PT_LOCKOUT_RECOVERY, &lockout_recovery_);
84   if (result != TPM_RC_SUCCESS) {
85     LOG(ERROR) << "Error getting lockout recovery: " << GetErrorString(result);
86     return result;
87   }
88 
89   TPMI_YES_NO more_data;
90   TPMS_CAPABILITY_DATA capability_data;
91   result = factory_.GetTpm()->GetCapabilitySync(TPM_CAP_ALGS,
92                                                 TPM_ALG_RSA,
93                                                 1,  // There is only one value.
94                                                 &more_data,
95                                                 &capability_data,
96                                                 nullptr);
97   if (result) {
98     LOG(ERROR) << __func__ << ": " << GetErrorString(result);
99     return result;
100   }
101   if (capability_data.capability != TPM_CAP_ALGS ||
102       capability_data.data.algorithms.count != 1) {
103     LOG(ERROR) << __func__ << ": Unexpected capability data.";
104     return SAPI_RC_MALFORMED_RESPONSE;
105   }
106   if (capability_data.data.algorithms.alg_properties[0].alg == TPM_ALG_RSA) {
107     rsa_flags_ =
108         capability_data.data.algorithms.alg_properties[0].alg_properties;
109   }
110   result = factory_.GetTpm()->GetCapabilitySync(TPM_CAP_ALGS,
111                                                 TPM_ALG_ECC,
112                                                 1,  // There is only one value.
113                                                 &more_data,
114                                                 &capability_data,
115                                                 nullptr);
116   if (result) {
117     LOG(ERROR) << __func__ << ": " << GetErrorString(result);
118     return result;
119   }
120   if (capability_data.capability != TPM_CAP_ALGS ||
121       capability_data.data.algorithms.count != 1) {
122     LOG(ERROR) << __func__ << ": Unexpected capability data.";
123     return SAPI_RC_MALFORMED_RESPONSE;
124   }
125   if (capability_data.data.algorithms.alg_properties[0].alg == TPM_ALG_ECC) {
126     ecc_flags_ =
127         capability_data.data.algorithms.alg_properties[0].alg_properties;
128   }
129   initialized_ = true;
130   return TPM_RC_SUCCESS;
131 }
132 
IsOwnerPasswordSet()133 bool TpmStateImpl::IsOwnerPasswordSet() {
134   CHECK(initialized_);
135   return ((permanent_flags_ & kOwnerAuthSetMask) == kOwnerAuthSetMask);
136 }
137 
IsEndorsementPasswordSet()138 bool TpmStateImpl::IsEndorsementPasswordSet() {
139   CHECK(initialized_);
140   return ((permanent_flags_ & kEndorsementAuthSetMask) ==
141           kEndorsementAuthSetMask);
142 }
143 
IsLockoutPasswordSet()144 bool TpmStateImpl::IsLockoutPasswordSet() {
145   CHECK(initialized_);
146   return ((permanent_flags_ & kLockoutAuthSetMask) == kLockoutAuthSetMask);
147 }
148 
IsOwned()149 bool TpmStateImpl::IsOwned() {
150   return (IsOwnerPasswordSet() &&
151           IsEndorsementPasswordSet() &&
152           IsLockoutPasswordSet());
153 }
154 
IsInLockout()155 bool TpmStateImpl::IsInLockout() {
156   CHECK(initialized_);
157   return ((permanent_flags_ & kInLockoutMask) == kInLockoutMask);
158 }
159 
IsPlatformHierarchyEnabled()160 bool TpmStateImpl::IsPlatformHierarchyEnabled() {
161   CHECK(initialized_);
162   return ((startup_clear_flags_ & kPlatformHierarchyMask) ==
163       kPlatformHierarchyMask);
164 }
165 
IsStorageHierarchyEnabled()166 bool TpmStateImpl::IsStorageHierarchyEnabled() {
167   CHECK(initialized_);
168   return ((startup_clear_flags_ & kStorageHierarchyMask) ==
169       kStorageHierarchyMask);
170 }
171 
IsEndorsementHierarchyEnabled()172 bool TpmStateImpl::IsEndorsementHierarchyEnabled() {
173   CHECK(initialized_);
174   return ((startup_clear_flags_ & kEndorsementHierarchyMask) ==
175       kEndorsementHierarchyMask);
176 }
177 
IsEnabled()178 bool TpmStateImpl::IsEnabled() {
179   return (!IsPlatformHierarchyEnabled() &&
180           IsStorageHierarchyEnabled() &&
181           IsEndorsementHierarchyEnabled());
182 }
183 
WasShutdownOrderly()184 bool TpmStateImpl::WasShutdownOrderly() {
185   CHECK(initialized_);
186   return ((startup_clear_flags_ & kOrderlyShutdownMask) ==
187       kOrderlyShutdownMask);
188 }
189 
IsRSASupported()190 bool TpmStateImpl::IsRSASupported() {
191   CHECK(initialized_);
192   return ((rsa_flags_ & kAsymmetricAlgMask) == kAsymmetricAlgMask);
193 }
194 
IsECCSupported()195 bool TpmStateImpl::IsECCSupported() {
196   CHECK(initialized_);
197   return ((ecc_flags_ & kAsymmetricAlgMask) == kAsymmetricAlgMask);
198 }
199 
GetLockoutCounter()200 uint32_t TpmStateImpl::GetLockoutCounter() {
201   CHECK(initialized_);
202   return lockout_counter_;
203 }
204 
GetLockoutThreshold()205 uint32_t TpmStateImpl::GetLockoutThreshold() {
206   CHECK(initialized_);
207   return lockout_threshold_;
208 }
209 
GetLockoutInterval()210 uint32_t TpmStateImpl::GetLockoutInterval() {
211   CHECK(initialized_);
212   return lockout_interval_;
213 }
214 
GetLockoutRecovery()215 uint32_t TpmStateImpl::GetLockoutRecovery() {
216   CHECK(initialized_);
217   return lockout_recovery_;
218 }
219 
GetTpmProperty(uint32_t property,uint32_t * value)220 TPM_RC TpmStateImpl::GetTpmProperty(uint32_t property,
221                                     uint32_t* value) {
222   CHECK(value);
223   TPMI_YES_NO more_data;
224   TPMS_CAPABILITY_DATA capability_data;
225   TPM_RC result = factory_.GetTpm()->GetCapabilitySync(TPM_CAP_TPM_PROPERTIES,
226                                                        property,
227                                                        1,  // Only one property.
228                                                        &more_data,
229                                                        &capability_data,
230                                                        nullptr);
231   if (result != TPM_RC_SUCCESS) {
232     LOG(ERROR) << __func__ << ": " << GetErrorString(result);
233     return result;
234   }
235   if (capability_data.capability != TPM_CAP_TPM_PROPERTIES ||
236       capability_data.data.tpm_properties.count != 1 ||
237       capability_data.data.tpm_properties.tpm_property[0].property !=
238       property) {
239     LOG(ERROR) << __func__ << ": Unexpected capability data.";
240     return SAPI_RC_MALFORMED_RESPONSE;
241   }
242   *value = capability_data.data.tpm_properties.tpm_property[0].value;
243   return TPM_RC_SUCCESS;
244 }
245 
246 }  // namespace trunks
247