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
40namespace {
41
42const char kPlatformPassword[] = "cros-platform";
43const char kWellKnownPassword[] = "cros-password";
44const size_t kMaxPasswordLength = 32;
45// The below maximum is defined in TPM 2.0 Library Spec Part 2 Section 13.1
46const 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).
52std::string NameFromHandle(trunks::TPM_HANDLE handle) {
53  std::string name;
54  trunks::Serialize_TPM_HANDLE(handle, &name);
55  return name;
56}
57
58std::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
72namespace trunks {
73
74TpmUtilityImpl::TpmUtilityImpl(const TrunksFactory& factory)
75    : factory_(factory) {
76  crypto::EnsureOpenSSLInit();
77}
78
79TpmUtilityImpl::~TpmUtilityImpl() {
80}
81
82TPM_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
99TPM_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
126void 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
134TPM_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
182TPM_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
248TPM_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
321TPM_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
328TPM_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
351TPM_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
372TPM_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
409TPM_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
472TPM_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
541TPM_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
620TPM_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
678TPM_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
716TPM_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
771TPM_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
855TPM_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
957TPM_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
996TPM_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
1013TPM_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
1034TPM_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
1096TPM_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
1133TPM_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
1143TPM_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
1178TPM_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
1234TPM_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
1270TPM_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
1308TPM_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
1356TPM_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
1405TPM_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
1425TPM_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
1458TPM_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
1484TPM_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
1614TPM_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
1702TPMT_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
1729TPM_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
1745TPM_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
1755TPM_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
1780TPM_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
1806TPM_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
1854TPM_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