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