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