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