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).
NameFromHandle(trunks::TPM_HANDLE handle)53 std::string NameFromHandle(trunks::TPM_HANDLE handle) {
54   std::string name;
55   trunks::Serialize_TPM_HANDLE(handle, &name);
56   return name;
57 }
58 
HashString(const std::string & plaintext,trunks::TPM_ALG_ID hash_alg)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 
TpmUtilityImpl(const TrunksFactory & factory)75 TpmUtilityImpl::TpmUtilityImpl(const TrunksFactory& factory)
76     : factory_(factory) {
77   crypto::EnsureOpenSSLInit();
78 }
79 
~TpmUtilityImpl()80 TpmUtilityImpl::~TpmUtilityImpl() {}
81 
Startup()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 
Clear()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 
Shutdown()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 
InitializeTpm()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 
AllocatePCR(const std::string & platform_password)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 
TakeOwnership(const std::string & owner_password,const std::string & endorsement_password,const std::string & lockout_password)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 
StirRandom(const std::string & entropy_data,AuthorizationDelegate * delegate)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 
GenerateRandom(size_t num_bytes,AuthorizationDelegate * delegate,std::string * random_data)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 
ExtendPCR(int pcr_index,const std::string & extend_data,AuthorizationDelegate * delegate)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 
ReadPCR(int pcr_index,std::string * pcr_value)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 
AsymmetricEncrypt(TPM_HANDLE key_handle,TPM_ALG_ID scheme,TPM_ALG_ID hash_alg,const std::string & plaintext,AuthorizationDelegate * delegate,std::string * ciphertext)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 
AsymmetricDecrypt(TPM_HANDLE key_handle,TPM_ALG_ID scheme,TPM_ALG_ID hash_alg,const std::string & ciphertext,AuthorizationDelegate * delegate,std::string * plaintext)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 
Sign(TPM_HANDLE key_handle,TPM_ALG_ID scheme,TPM_ALG_ID hash_alg,const std::string & plaintext,AuthorizationDelegate * delegate,std::string * signature)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 
Verify(TPM_HANDLE key_handle,TPM_ALG_ID scheme,TPM_ALG_ID hash_alg,const std::string & plaintext,const std::string & signature,AuthorizationDelegate * delegate)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 
CertifyCreation(TPM_HANDLE key_handle,const std::string & creation_blob)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 
ChangeKeyAuthorizationData(TPM_HANDLE key_handle,const std::string & new_password,AuthorizationDelegate * delegate,std::string * key_blob)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 
ImportRSAKey(AsymmetricKeyUsage key_type,const std::string & modulus,uint32_t public_exponent,const std::string & prime_factor,const std::string & password,AuthorizationDelegate * delegate,std::string * key_blob)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 
CreateRSAKeyPair(AsymmetricKeyUsage key_type,int modulus_bits,uint32_t public_exponent,const std::string & password,const std::string & policy_digest,bool use_only_policy_authorization,int creation_pcr_index,AuthorizationDelegate * delegate,std::string * key_blob,std::string * creation_blob)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 
LoadKey(const std::string & key_blob,AuthorizationDelegate * delegate,TPM_HANDLE * key_handle)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 
GetKeyName(TPM_HANDLE handle,std::string * name)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 
GetKeyPublicArea(TPM_HANDLE handle,TPMT_PUBLIC * public_data)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 
SealData(const std::string & data_to_seal,const std::string & policy_digest,AuthorizationDelegate * delegate,std::string * sealed_data)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 
UnsealData(const std::string & sealed_data,AuthorizationDelegate * delegate,std::string * unsealed_data)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 
StartSession(HmacSession * session)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 
GetPolicyDigestForPcrValue(int pcr_index,const std::string & pcr_value,std::string * policy_digest)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 
DefineNVSpace(uint32_t index,size_t num_bytes,TPMA_NV attributes,const std::string & authorization_value,const std::string & policy_digest,AuthorizationDelegate * delegate)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 
DestroyNVSpace(uint32_t index,AuthorizationDelegate * delegate)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 
LockNVSpace(uint32_t index,bool lock_read,bool lock_write,bool using_owner_authorization,AuthorizationDelegate * delegate)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 
WriteNVSpace(uint32_t index,uint32_t offset,const std::string & nvram_data,bool using_owner_authorization,bool extend,AuthorizationDelegate * delegate)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 
ReadNVSpace(uint32_t index,uint32_t offset,size_t num_bytes,bool using_owner_authorization,std::string * nvram_data,AuthorizationDelegate * delegate)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 
GetNVSpaceName(uint32_t index,std::string * name)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 
GetNVSpacePublicArea(uint32_t index,TPMS_NV_PUBLIC * public_data)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 
ListNVSpaces(std::vector<uint32_t> * index_list)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 
SetDictionaryAttackParameters(uint32_t max_tries,uint32_t recovery_time,uint32_t lockout_recovery,AuthorizationDelegate * delegate)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 
ResetDictionaryAttackLock(AuthorizationDelegate * delegate)1469 TPM_RC TpmUtilityImpl::ResetDictionaryAttackLock(
1470     AuthorizationDelegate* delegate) {
1471   return factory_.GetTpm()->DictionaryAttackLockResetSync(
1472       TPM_RH_LOCKOUT, NameFromHandle(TPM_RH_LOCKOUT), delegate);
1473 }
1474 
SetKnownOwnerPassword(const std::string & known_owner_password)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 
CreateStorageRootKeys(const std::string & owner_password)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 
CreateSaltingKey(const std::string & owner_password)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 
CreateDefaultPublicArea(TPM_ALG_ID key_alg)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 
SetHierarchyAuthorization(TPMI_RH_HIERARCHY_AUTH hierarchy,const std::string & password,AuthorizationDelegate * authorization)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 
DisablePlatformHierarchy(AuthorizationDelegate * authorization)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 
ComputeKeyName(const TPMT_PUBLIC & public_area,std::string * object_name)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 
ComputeNVSpaceName(const TPMS_NV_PUBLIC & nv_public_area,std::string * nv_name)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 
EncryptPrivateData(const TPMT_SENSITIVE & sensitive_area,const TPMT_PUBLIC & public_area,TPM2B_PRIVATE * encrypted_private_data,TPM2B_DATA * encryption_key)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*>(string_as_array(&private_data_string)),
1833       unencrypted_private_data.size(), &key, iv, &iv_in, AES_ENCRYPT);
1834   *encrypted_private_data = Make_TPM2B_PRIVATE(private_data_string);
1835   if (result != TPM_RC_SUCCESS) {
1836     LOG(ERROR) << __func__
1837                << ": Error making private area: " << GetErrorString(result);
1838     return result;
1839   }
1840   return TPM_RC_SUCCESS;
1841 }
1842 
DoesPersistentKeyExist(TPMI_DH_PERSISTENT key_handle,bool * exists)1843 TPM_RC TpmUtilityImpl::DoesPersistentKeyExist(TPMI_DH_PERSISTENT key_handle,
1844                                               bool* exists) {
1845   TPM_RC result;
1846   TPMI_YES_NO more_data = YES;
1847   TPMS_CAPABILITY_DATA capability_data;
1848   result = factory_.GetTpm()->GetCapabilitySync(
1849       TPM_CAP_HANDLES, key_handle, 1 /*property_count*/, &more_data,
1850       &capability_data, nullptr /*authorization_delegate*/);
1851   if (result != TPM_RC_SUCCESS) {
1852     LOG(ERROR) << __func__
1853                << ": Error querying handles: " << GetErrorString(result);
1854     return result;
1855   }
1856   TPML_HANDLE& handles = capability_data.data.handles;
1857   *exists = (handles.count == 1 && handles.handle[0] == key_handle);
1858   return TPM_RC_SUCCESS;
1859 }
1860 
1861 }  // namespace trunks
1862