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