1bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// 2bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// Copyright (C) 2014 The Android Open Source Project 3bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// 4bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// Licensed under the Apache License, Version 2.0 (the "License"); 5bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// you may not use this file except in compliance with the License. 6bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// You may obtain a copy of the License at 7bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// 8bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// http://www.apache.org/licenses/LICENSE-2.0 9bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// 10bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// Unless required by applicable law or agreed to in writing, software 11bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// distributed under the License is distributed on an "AS IS" BASIS, 12bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// See the License for the specific language governing permissions and 14bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// limitations under the License. 15bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// 16c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn 17c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn#include "trunks/tpm_utility_impl.h" 18c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn 1930c921db09d27768acc1ea0d8b6a9c8e814f931aLuis Hector Chavez#include <memory> 2030c921db09d27768acc1ea0d8b6a9c8e814f931aLuis Hector Chavez 21c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn#include <base/logging.h> 22887ccbcc4db5fa0b5221018296aa49b86a5ac26fUtkarsh Sanghi#include <base/sha1.h> 23e31034f28641c9bc3e5576cab6d2c7d918bb427cUtkarsh Sanghi#include <base/stl_util.h> 2487b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn#include <crypto/openssl_util.h> 25e31034f28641c9bc3e5576cab6d2c7d918bb427cUtkarsh Sanghi#include <crypto/secure_hash.h> 26e31034f28641c9bc3e5576cab6d2c7d918bb427cUtkarsh Sanghi#include <crypto/sha2.h> 2733ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi#include <openssl/aes.h> 2833ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi#include <openssl/rand.h> 29c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn 30c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn#include "trunks/authorization_delegate.h" 310ebbc58fe6d45378a5b502c33eb1c4289fd8b05bUtkarsh Sanghi#include "trunks/blob_parser.h" 3203d54dfbcbdd04384e8c0419b7c45282664a2c1aDarren Krahn#include "trunks/error_codes.h" 3333ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi#include "trunks/hmac_authorization_delegate.h" 34ff7f2da556b21253a52abbc82e7cf7bee54a850eUtkarsh Sanghi#include "trunks/hmac_session.h" 35a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi#include "trunks/policy_session.h" 362ee32a9d61896f544d87ecee24dc25cc33c9ebb3Utkarsh Sanghi#include "trunks/scoped_key_handle.h" 3739dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi#include "trunks/tpm_constants.h" 38c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn#include "trunks/tpm_state.h" 39c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn#include "trunks/trunks_factory.h" 40c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn 41c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahnnamespace { 42c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn 43c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahnconst char kPlatformPassword[] = "cros-platform"; 442ee32a9d61896f544d87ecee24dc25cc33c9ebb3Utkarsh Sanghiconst char kWellKnownPassword[] = "cros-password"; 45e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghiconst size_t kMaxPasswordLength = 32; 4639dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi// The below maximum is defined in TPM 2.0 Library Spec Part 2 Section 13.1 474dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahnconst uint32_t kMaxNVSpaceIndex = (1 << 24) - 1; 48c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn 49c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn// Returns a serialized representation of the unmodified handle. This is useful 50c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn// for predefined handle values, like TPM_RH_OWNER. For details on what types of 51c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn// handles use this name formula see Table 3 in the TPM 2.0 Library Spec Part 1 52c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn// (Section 16 - Names). 53c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahnstd::string NameFromHandle(trunks::TPM_HANDLE handle) { 54c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn std::string name; 55c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn trunks::Serialize_TPM_HANDLE(handle, &name); 56c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn return name; 57c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn} 58c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn 59887ccbcc4db5fa0b5221018296aa49b86a5ac26fUtkarsh Sanghistd::string HashString(const std::string& plaintext, 60887ccbcc4db5fa0b5221018296aa49b86a5ac26fUtkarsh Sanghi trunks::TPM_ALG_ID hash_alg) { 61e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi switch (hash_alg) { 62e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi case trunks::TPM_ALG_SHA1: 63887ccbcc4db5fa0b5221018296aa49b86a5ac26fUtkarsh Sanghi return base::SHA1HashString(plaintext); 64e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi case trunks::TPM_ALG_SHA256: 65887ccbcc4db5fa0b5221018296aa49b86a5ac26fUtkarsh Sanghi return crypto::SHA256HashString(plaintext); 66e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi } 67e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi NOTREACHED(); 68887ccbcc4db5fa0b5221018296aa49b86a5ac26fUtkarsh Sanghi return std::string(); 69e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi} 70e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi 71c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn} // namespace 72c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn 73c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahnnamespace trunks { 74c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn 75c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren KrahnTpmUtilityImpl::TpmUtilityImpl(const TrunksFactory& factory) 7687b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn : factory_(factory) { 7787b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn crypto::EnsureOpenSSLInit(); 7887b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn} 79c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn 804dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren KrahnTpmUtilityImpl::~TpmUtilityImpl() {} 81c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn 8203d54dfbcbdd04384e8c0419b7c45282664a2c1aDarren KrahnTPM_RC TpmUtilityImpl::Startup() { 8303d54dfbcbdd04384e8c0419b7c45282664a2c1aDarren Krahn TPM_RC result = TPM_RC_SUCCESS; 8403d54dfbcbdd04384e8c0419b7c45282664a2c1aDarren Krahn Tpm* tpm = factory_.GetTpm(); 85c04decde2a6e9b74395f402818852e752534254bUtkarsh Sanghi result = tpm->StartupSync(TPM_SU_CLEAR, nullptr); 8603d54dfbcbdd04384e8c0419b7c45282664a2c1aDarren Krahn // Ignore TPM_RC_INITIALIZE, that means it was already started. 8703d54dfbcbdd04384e8c0419b7c45282664a2c1aDarren Krahn if (result && result != TPM_RC_INITIALIZE) { 8803d54dfbcbdd04384e8c0419b7c45282664a2c1aDarren Krahn LOG(ERROR) << __func__ << ": " << GetErrorString(result); 8903d54dfbcbdd04384e8c0419b7c45282664a2c1aDarren Krahn return result; 9003d54dfbcbdd04384e8c0419b7c45282664a2c1aDarren Krahn } 91c04decde2a6e9b74395f402818852e752534254bUtkarsh Sanghi result = tpm->SelfTestSync(YES /* Full test. */, nullptr); 9203d54dfbcbdd04384e8c0419b7c45282664a2c1aDarren Krahn if (result) { 9303d54dfbcbdd04384e8c0419b7c45282664a2c1aDarren Krahn LOG(ERROR) << __func__ << ": " << GetErrorString(result); 9403d54dfbcbdd04384e8c0419b7c45282664a2c1aDarren Krahn return result; 9503d54dfbcbdd04384e8c0419b7c45282664a2c1aDarren Krahn } 9603d54dfbcbdd04384e8c0419b7c45282664a2c1aDarren Krahn return TPM_RC_SUCCESS; 9703d54dfbcbdd04384e8c0419b7c45282664a2c1aDarren Krahn} 9803d54dfbcbdd04384e8c0419b7c45282664a2c1aDarren Krahn 99d75dcae8a010d1ced7554dd25a440bee350a2d06Utkarsh SanghiTPM_RC TpmUtilityImpl::Clear() { 100d75dcae8a010d1ced7554dd25a440bee350a2d06Utkarsh Sanghi TPM_RC result = TPM_RC_SUCCESS; 10130c921db09d27768acc1ea0d8b6a9c8e814f931aLuis Hector Chavez std::unique_ptr<AuthorizationDelegate> password_delegate( 102d75dcae8a010d1ced7554dd25a440bee350a2d06Utkarsh Sanghi factory_.GetPasswordAuthorization("")); 103d75dcae8a010d1ced7554dd25a440bee350a2d06Utkarsh Sanghi result = factory_.GetTpm()->ClearSync(TPM_RH_PLATFORM, 104d75dcae8a010d1ced7554dd25a440bee350a2d06Utkarsh Sanghi NameFromHandle(TPM_RH_PLATFORM), 105d75dcae8a010d1ced7554dd25a440bee350a2d06Utkarsh Sanghi password_delegate.get()); 106d75dcae8a010d1ced7554dd25a440bee350a2d06Utkarsh Sanghi // If there was an error in the initialization, platform auth is in a bad 107d75dcae8a010d1ced7554dd25a440bee350a2d06Utkarsh Sanghi // state. 108d75dcae8a010d1ced7554dd25a440bee350a2d06Utkarsh Sanghi if (result == TPM_RC_AUTH_MISSING) { 10930c921db09d27768acc1ea0d8b6a9c8e814f931aLuis Hector Chavez std::unique_ptr<AuthorizationDelegate> authorization( 110d75dcae8a010d1ced7554dd25a440bee350a2d06Utkarsh Sanghi factory_.GetPasswordAuthorization(kPlatformPassword)); 1114dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn result = factory_.GetTpm()->ClearSync( 1124dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn TPM_RH_PLATFORM, NameFromHandle(TPM_RH_PLATFORM), authorization.get()); 113d75dcae8a010d1ced7554dd25a440bee350a2d06Utkarsh Sanghi } 114d75dcae8a010d1ced7554dd25a440bee350a2d06Utkarsh Sanghi if (GetFormatOneError(result) == TPM_RC_BAD_AUTH) { 115b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(INFO) << __func__ 116b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Clear failed because of BAD_AUTH. This probably means " 117d75dcae8a010d1ced7554dd25a440bee350a2d06Utkarsh Sanghi << "that the TPM was already initialized."; 118d75dcae8a010d1ced7554dd25a440bee350a2d06Utkarsh Sanghi return result; 119d75dcae8a010d1ced7554dd25a440bee350a2d06Utkarsh Sanghi } 120d75dcae8a010d1ced7554dd25a440bee350a2d06Utkarsh Sanghi if (result) { 121b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 122b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Failed to clear the TPM: " << GetErrorString(result); 123d75dcae8a010d1ced7554dd25a440bee350a2d06Utkarsh Sanghi } 124d75dcae8a010d1ced7554dd25a440bee350a2d06Utkarsh Sanghi return result; 125d75dcae8a010d1ced7554dd25a440bee350a2d06Utkarsh Sanghi} 126d75dcae8a010d1ced7554dd25a440bee350a2d06Utkarsh Sanghi 127e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghivoid TpmUtilityImpl::Shutdown() { 128c04decde2a6e9b74395f402818852e752534254bUtkarsh Sanghi TPM_RC return_code = factory_.GetTpm()->ShutdownSync(TPM_SU_CLEAR, nullptr); 129e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi if (return_code && return_code != TPM_RC_INITIALIZE) { 130e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi // This should not happen, but if it does, there is nothing we can do. 131b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 132b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Error shutting down: " << GetErrorString(return_code); 133e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi } 134e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi} 135e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi 136c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren KrahnTPM_RC TpmUtilityImpl::InitializeTpm() { 137c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn TPM_RC result = TPM_RC_SUCCESS; 13830c921db09d27768acc1ea0d8b6a9c8e814f931aLuis Hector Chavez std::unique_ptr<TpmState> tpm_state(factory_.GetTpmState()); 139c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn result = tpm_state->Initialize(); 140c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn if (result) { 14103d54dfbcbdd04384e8c0419b7c45282664a2c1aDarren Krahn LOG(ERROR) << __func__ << ": " << GetErrorString(result); 142c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn return result; 143c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn } 144c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn // Warn about various unexpected conditions. 145c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn if (!tpm_state->WasShutdownOrderly()) { 146b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(WARNING) << __func__ 147b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": WARNING: The last TPM shutdown was not orderly."; 148c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn } 149c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn if (tpm_state->IsInLockout()) { 150b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(WARNING) << __func__ << ": WARNING: The TPM is currently in lockout."; 151c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn } 152c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn 153c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn // We expect the firmware has already locked down the platform hierarchy. If 154c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn // it hasn't, do it now. 155c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn if (tpm_state->IsPlatformHierarchyEnabled()) { 15630c921db09d27768acc1ea0d8b6a9c8e814f931aLuis Hector Chavez std::unique_ptr<AuthorizationDelegate> empty_password( 15752e2a45f585fbe34032eae5b094a092afdf217caDarren Krahn factory_.GetPasswordAuthorization("")); 1584dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn result = SetHierarchyAuthorization(TPM_RH_PLATFORM, kPlatformPassword, 15952e2a45f585fbe34032eae5b094a092afdf217caDarren Krahn empty_password.get()); 16052e2a45f585fbe34032eae5b094a092afdf217caDarren Krahn if (GetFormatOneError(result) == TPM_RC_BAD_AUTH) { 16152e2a45f585fbe34032eae5b094a092afdf217caDarren Krahn // Most likely the platform password has already been set. 16252e2a45f585fbe34032eae5b094a092afdf217caDarren Krahn result = TPM_RC_SUCCESS; 16352e2a45f585fbe34032eae5b094a092afdf217caDarren Krahn } 164e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi if (result != TPM_RC_SUCCESS) { 165e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi LOG(ERROR) << __func__ << ": " << GetErrorString(result); 166e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi return result; 167e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi } 168e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi result = AllocatePCR(kPlatformPassword); 169e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi if (result != TPM_RC_SUCCESS) { 17003d54dfbcbdd04384e8c0419b7c45282664a2c1aDarren Krahn LOG(ERROR) << __func__ << ": " << GetErrorString(result); 171c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn return result; 172c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn } 17330c921db09d27768acc1ea0d8b6a9c8e814f931aLuis Hector Chavez std::unique_ptr<AuthorizationDelegate> authorization( 174c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn factory_.GetPasswordAuthorization(kPlatformPassword)); 175c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn result = DisablePlatformHierarchy(authorization.get()); 176e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi if (result != TPM_RC_SUCCESS) { 17703d54dfbcbdd04384e8c0419b7c45282664a2c1aDarren Krahn LOG(ERROR) << __func__ << ": " << GetErrorString(result); 178c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn return result; 179c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn } 180c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn } 181c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn return TPM_RC_SUCCESS; 182c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn} 183c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn 184e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh SanghiTPM_RC TpmUtilityImpl::AllocatePCR(const std::string& platform_password) { 185e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi TPM_RC result; 186db30790da11248905f8dca02a933ebbdcf9e3ff9Darren Krahn TPMI_YES_NO more_data = YES; 187db30790da11248905f8dca02a933ebbdcf9e3ff9Darren Krahn TPMS_CAPABILITY_DATA capability_data; 188db30790da11248905f8dca02a933ebbdcf9e3ff9Darren Krahn result = factory_.GetTpm()->GetCapabilitySync( 189db30790da11248905f8dca02a933ebbdcf9e3ff9Darren Krahn TPM_CAP_PCRS, 0 /*property (not used)*/, 1 /*property_count*/, &more_data, 190db30790da11248905f8dca02a933ebbdcf9e3ff9Darren Krahn &capability_data, nullptr /*authorization_delegate*/); 191db30790da11248905f8dca02a933ebbdcf9e3ff9Darren Krahn if (result != TPM_RC_SUCCESS) { 192b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 193b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Error querying PCRs: " << GetErrorString(result); 194db30790da11248905f8dca02a933ebbdcf9e3ff9Darren Krahn return result; 195db30790da11248905f8dca02a933ebbdcf9e3ff9Darren Krahn } 196db30790da11248905f8dca02a933ebbdcf9e3ff9Darren Krahn TPML_PCR_SELECTION& existing_pcrs = capability_data.data.assigned_pcr; 197db30790da11248905f8dca02a933ebbdcf9e3ff9Darren Krahn bool sha256_needed = true; 198db30790da11248905f8dca02a933ebbdcf9e3ff9Darren Krahn std::vector<TPMI_ALG_HASH> pcr_banks_to_remove; 199db30790da11248905f8dca02a933ebbdcf9e3ff9Darren Krahn for (uint32_t i = 0; i < existing_pcrs.count; ++i) { 200db30790da11248905f8dca02a933ebbdcf9e3ff9Darren Krahn if (existing_pcrs.pcr_selections[i].hash == TPM_ALG_SHA256) { 201db30790da11248905f8dca02a933ebbdcf9e3ff9Darren Krahn sha256_needed = false; 202db30790da11248905f8dca02a933ebbdcf9e3ff9Darren Krahn } else { 203db30790da11248905f8dca02a933ebbdcf9e3ff9Darren Krahn pcr_banks_to_remove.push_back(existing_pcrs.pcr_selections[i].hash); 204db30790da11248905f8dca02a933ebbdcf9e3ff9Darren Krahn } 205db30790da11248905f8dca02a933ebbdcf9e3ff9Darren Krahn } 206db30790da11248905f8dca02a933ebbdcf9e3ff9Darren Krahn if (!sha256_needed && pcr_banks_to_remove.empty()) { 207db30790da11248905f8dca02a933ebbdcf9e3ff9Darren Krahn return TPM_RC_SUCCESS; 208db30790da11248905f8dca02a933ebbdcf9e3ff9Darren Krahn } 209e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi TPML_PCR_SELECTION pcr_allocation; 210db30790da11248905f8dca02a933ebbdcf9e3ff9Darren Krahn memset(&pcr_allocation, 0, sizeof(pcr_allocation)); 211db30790da11248905f8dca02a933ebbdcf9e3ff9Darren Krahn if (sha256_needed) { 212db30790da11248905f8dca02a933ebbdcf9e3ff9Darren Krahn pcr_allocation.pcr_selections[pcr_allocation.count].hash = TPM_ALG_SHA256; 213db30790da11248905f8dca02a933ebbdcf9e3ff9Darren Krahn pcr_allocation.pcr_selections[pcr_allocation.count].sizeof_select = 214db30790da11248905f8dca02a933ebbdcf9e3ff9Darren Krahn PCR_SELECT_MIN; 215db30790da11248905f8dca02a933ebbdcf9e3ff9Darren Krahn for (int i = 0; i < PCR_SELECT_MIN; ++i) { 216db30790da11248905f8dca02a933ebbdcf9e3ff9Darren Krahn pcr_allocation.pcr_selections[pcr_allocation.count].pcr_select[i] = 0xff; 217db30790da11248905f8dca02a933ebbdcf9e3ff9Darren Krahn } 218db30790da11248905f8dca02a933ebbdcf9e3ff9Darren Krahn ++pcr_allocation.count; 219db30790da11248905f8dca02a933ebbdcf9e3ff9Darren Krahn } 220db30790da11248905f8dca02a933ebbdcf9e3ff9Darren Krahn for (auto pcr_type : pcr_banks_to_remove) { 221db30790da11248905f8dca02a933ebbdcf9e3ff9Darren Krahn pcr_allocation.pcr_selections[pcr_allocation.count].hash = pcr_type; 222db30790da11248905f8dca02a933ebbdcf9e3ff9Darren Krahn pcr_allocation.pcr_selections[pcr_allocation.count].sizeof_select = 223db30790da11248905f8dca02a933ebbdcf9e3ff9Darren Krahn PCR_SELECT_MAX; 224db30790da11248905f8dca02a933ebbdcf9e3ff9Darren Krahn ++pcr_allocation.count; 225db30790da11248905f8dca02a933ebbdcf9e3ff9Darren Krahn } 22630c921db09d27768acc1ea0d8b6a9c8e814f931aLuis Hector Chavez std::unique_ptr<AuthorizationDelegate> platform_delegate( 227e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi factory_.GetPasswordAuthorization(platform_password)); 228e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi TPMI_YES_NO allocation_success; 229e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi uint32_t max_pcr; 230e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi uint32_t size_needed; 231e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi uint32_t size_available; 2324dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn result = factory_.GetTpm()->PCR_AllocateSync( 2334dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn TPM_RH_PLATFORM, NameFromHandle(TPM_RH_PLATFORM), pcr_allocation, 2344dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn &allocation_success, &max_pcr, &size_needed, &size_available, 2354dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn platform_delegate.get()); 236e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi if (result != TPM_RC_SUCCESS) { 237b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 238b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Error allocating PCRs: " << GetErrorString(result); 239e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi return result; 240e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi } 241e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi if (allocation_success != YES) { 242b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": PCR allocation unsuccessful."; 243e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi return TPM_RC_FAILURE; 244e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi } 245e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi return TPM_RC_SUCCESS; 246e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi} 247e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi 2482ee32a9d61896f544d87ecee24dc25cc33c9ebb3Utkarsh SanghiTPM_RC TpmUtilityImpl::TakeOwnership(const std::string& owner_password, 2492ee32a9d61896f544d87ecee24dc25cc33c9ebb3Utkarsh Sanghi const std::string& endorsement_password, 2502ee32a9d61896f544d87ecee24dc25cc33c9ebb3Utkarsh Sanghi const std::string& lockout_password) { 2512ee32a9d61896f544d87ecee24dc25cc33c9ebb3Utkarsh Sanghi // First we set the storage hierarchy authorization to the well know default 2522ee32a9d61896f544d87ecee24dc25cc33c9ebb3Utkarsh Sanghi // password. 25366d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi TPM_RC result = TPM_RC_SUCCESS; 25466d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi result = SetKnownOwnerPassword(kWellKnownPassword); 25566d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi if (result != TPM_RC_SUCCESS) { 256b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Error injecting known password: " 257b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << GetErrorString(result); 2582ee32a9d61896f544d87ecee24dc25cc33c9ebb3Utkarsh Sanghi return result; 2592ee32a9d61896f544d87ecee24dc25cc33c9ebb3Utkarsh Sanghi } 26066d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi 2612ee32a9d61896f544d87ecee24dc25cc33c9ebb3Utkarsh Sanghi result = CreateStorageRootKeys(kWellKnownPassword); 2622ee32a9d61896f544d87ecee24dc25cc33c9ebb3Utkarsh Sanghi if (result) { 263b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 264b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Error creating SRKs: " << GetErrorString(result); 2652ee32a9d61896f544d87ecee24dc25cc33c9ebb3Utkarsh Sanghi return result; 2662ee32a9d61896f544d87ecee24dc25cc33c9ebb3Utkarsh Sanghi } 2672ee32a9d61896f544d87ecee24dc25cc33c9ebb3Utkarsh Sanghi result = CreateSaltingKey(kWellKnownPassword); 2682ee32a9d61896f544d87ecee24dc25cc33c9ebb3Utkarsh Sanghi if (result) { 269b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 270b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Error creating salting key: " << GetErrorString(result); 2712ee32a9d61896f544d87ecee24dc25cc33c9ebb3Utkarsh Sanghi return result; 2722ee32a9d61896f544d87ecee24dc25cc33c9ebb3Utkarsh Sanghi } 27366d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi 27430c921db09d27768acc1ea0d8b6a9c8e814f931aLuis Hector Chavez std::unique_ptr<HmacSession> session = factory_.GetHmacSession(); 2752ff7e22ba2ef3bb7ce2747b1b9706dd242ef9284Utkarsh Sanghi result = session->StartUnboundSession(true); 2762ff7e22ba2ef3bb7ce2747b1b9706dd242ef9284Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 277b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Error initializing AuthorizationSession: " 2782ee32a9d61896f544d87ecee24dc25cc33c9ebb3Utkarsh Sanghi << GetErrorString(result); 2792ee32a9d61896f544d87ecee24dc25cc33c9ebb3Utkarsh Sanghi return result; 2802ee32a9d61896f544d87ecee24dc25cc33c9ebb3Utkarsh Sanghi } 28130c921db09d27768acc1ea0d8b6a9c8e814f931aLuis Hector Chavez std::unique_ptr<TpmState> tpm_state(factory_.GetTpmState()); 2822ee32a9d61896f544d87ecee24dc25cc33c9ebb3Utkarsh Sanghi result = tpm_state->Initialize(); 2832ff7e22ba2ef3bb7ce2747b1b9706dd242ef9284Utkarsh Sanghi session->SetEntityAuthorizationValue(""); 2842ff7e22ba2ef3bb7ce2747b1b9706dd242ef9284Utkarsh Sanghi session->SetFutureAuthorizationValue(endorsement_password); 2852ee32a9d61896f544d87ecee24dc25cc33c9ebb3Utkarsh Sanghi if (!tpm_state->IsEndorsementPasswordSet()) { 2864dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn result = SetHierarchyAuthorization(TPM_RH_ENDORSEMENT, endorsement_password, 2872ff7e22ba2ef3bb7ce2747b1b9706dd242ef9284Utkarsh Sanghi session->GetDelegate()); 2882ee32a9d61896f544d87ecee24dc25cc33c9ebb3Utkarsh Sanghi if (result) { 2892ee32a9d61896f544d87ecee24dc25cc33c9ebb3Utkarsh Sanghi LOG(ERROR) << __func__ << ": " << GetErrorString(result); 2902ee32a9d61896f544d87ecee24dc25cc33c9ebb3Utkarsh Sanghi return result; 2912ee32a9d61896f544d87ecee24dc25cc33c9ebb3Utkarsh Sanghi } 2922ee32a9d61896f544d87ecee24dc25cc33c9ebb3Utkarsh Sanghi } 2932ff7e22ba2ef3bb7ce2747b1b9706dd242ef9284Utkarsh Sanghi session->SetFutureAuthorizationValue(lockout_password); 2942ee32a9d61896f544d87ecee24dc25cc33c9ebb3Utkarsh Sanghi if (!tpm_state->IsLockoutPasswordSet()) { 2954dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn result = SetHierarchyAuthorization(TPM_RH_LOCKOUT, lockout_password, 2962ff7e22ba2ef3bb7ce2747b1b9706dd242ef9284Utkarsh Sanghi session->GetDelegate()); 2972ee32a9d61896f544d87ecee24dc25cc33c9ebb3Utkarsh Sanghi if (result) { 2982ee32a9d61896f544d87ecee24dc25cc33c9ebb3Utkarsh Sanghi LOG(ERROR) << __func__ << ": " << GetErrorString(result); 2992ee32a9d61896f544d87ecee24dc25cc33c9ebb3Utkarsh Sanghi return result; 3002ee32a9d61896f544d87ecee24dc25cc33c9ebb3Utkarsh Sanghi } 3012ee32a9d61896f544d87ecee24dc25cc33c9ebb3Utkarsh Sanghi } 30266d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi // We take ownership of owner hierarchy last. 30366d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi session->SetEntityAuthorizationValue(kWellKnownPassword); 30466d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi session->SetFutureAuthorizationValue(owner_password); 3054dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn result = SetHierarchyAuthorization(TPM_RH_OWNER, owner_password, 30666d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi session->GetDelegate()); 30766d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi if ((GetFormatOneError(result) == TPM_RC_BAD_AUTH) && 30866d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi tpm_state->IsOwnerPasswordSet()) { 309b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(WARNING) << __func__ 310b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Error changing owner password. This probably because " 31166d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi << "ownership is already taken."; 31266d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi return TPM_RC_SUCCESS; 31366d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi } else if (result != TPM_RC_SUCCESS) { 314b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Error changing owner authorization: " 3150f46c15b948ee17f5668c332a25a0dbaecb2cc47Utkarsh Sanghi << GetErrorString(result); 3160f46c15b948ee17f5668c332a25a0dbaecb2cc47Utkarsh Sanghi return result; 3170f46c15b948ee17f5668c332a25a0dbaecb2cc47Utkarsh Sanghi } 3180f46c15b948ee17f5668c332a25a0dbaecb2cc47Utkarsh Sanghi return TPM_RC_SUCCESS; 3190f46c15b948ee17f5668c332a25a0dbaecb2cc47Utkarsh Sanghi} 3200f46c15b948ee17f5668c332a25a0dbaecb2cc47Utkarsh Sanghi 3218b2bf63478b292937f85b3b0e215882af461a999Utkarsh SanghiTPM_RC TpmUtilityImpl::StirRandom(const std::string& entropy_data, 3225d3b9451ae2e912aefed0669dd50b2a777ea0ab2Utkarsh Sanghi AuthorizationDelegate* delegate) { 323e31034f28641c9bc3e5576cab6d2c7d918bb427cUtkarsh Sanghi std::string digest = crypto::SHA256HashString(entropy_data); 324e31034f28641c9bc3e5576cab6d2c7d918bb427cUtkarsh Sanghi TPM2B_SENSITIVE_DATA random_bytes = Make_TPM2B_SENSITIVE_DATA(digest); 3258b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi return factory_.GetTpm()->StirRandomSync(random_bytes, delegate); 326e31034f28641c9bc3e5576cab6d2c7d918bb427cUtkarsh Sanghi} 327e31034f28641c9bc3e5576cab6d2c7d918bb427cUtkarsh Sanghi 32835af244e7cf856a02e46ec8f186f36c53582757dUtkarsh SanghiTPM_RC TpmUtilityImpl::GenerateRandom(size_t num_bytes, 3295d3b9451ae2e912aefed0669dd50b2a777ea0ab2Utkarsh Sanghi AuthorizationDelegate* delegate, 330e31034f28641c9bc3e5576cab6d2c7d918bb427cUtkarsh Sanghi std::string* random_data) { 3318b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi CHECK(random_data); 33235af244e7cf856a02e46ec8f186f36c53582757dUtkarsh Sanghi size_t bytes_left = num_bytes; 333e31034f28641c9bc3e5576cab6d2c7d918bb427cUtkarsh Sanghi random_data->clear(); 334e31034f28641c9bc3e5576cab6d2c7d918bb427cUtkarsh Sanghi TPM_RC rc; 335e31034f28641c9bc3e5576cab6d2c7d918bb427cUtkarsh Sanghi TPM2B_DIGEST digest; 336e31034f28641c9bc3e5576cab6d2c7d918bb427cUtkarsh Sanghi while (bytes_left > 0) { 3374dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn rc = factory_.GetTpm()->GetRandomSync(bytes_left, &digest, delegate); 338e31034f28641c9bc3e5576cab6d2c7d918bb427cUtkarsh Sanghi if (rc) { 339b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Error getting random data from tpm."; 340e31034f28641c9bc3e5576cab6d2c7d918bb427cUtkarsh Sanghi return rc; 341e31034f28641c9bc3e5576cab6d2c7d918bb427cUtkarsh Sanghi } 342e31034f28641c9bc3e5576cab6d2c7d918bb427cUtkarsh Sanghi random_data->append(StringFrom_TPM2B_DIGEST(digest)); 343e31034f28641c9bc3e5576cab6d2c7d918bb427cUtkarsh Sanghi bytes_left -= digest.size; 344e31034f28641c9bc3e5576cab6d2c7d918bb427cUtkarsh Sanghi } 345e31034f28641c9bc3e5576cab6d2c7d918bb427cUtkarsh Sanghi CHECK_EQ(random_data->size(), num_bytes); 346e31034f28641c9bc3e5576cab6d2c7d918bb427cUtkarsh Sanghi return TPM_RC_SUCCESS; 347e31034f28641c9bc3e5576cab6d2c7d918bb427cUtkarsh Sanghi} 348e31034f28641c9bc3e5576cab6d2c7d918bb427cUtkarsh Sanghi 349579dd8a934c684f2e2a34d9aa2f67953320428acUtkarsh SanghiTPM_RC TpmUtilityImpl::ExtendPCR(int pcr_index, 3508b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi const std::string& extend_data, 3515d3b9451ae2e912aefed0669dd50b2a777ea0ab2Utkarsh Sanghi AuthorizationDelegate* delegate) { 352579dd8a934c684f2e2a34d9aa2f67953320428acUtkarsh Sanghi if (pcr_index < 0 || pcr_index >= IMPLEMENTATION_PCR) { 353b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Using a PCR index that isn't implemented."; 354579dd8a934c684f2e2a34d9aa2f67953320428acUtkarsh Sanghi return TPM_RC_FAILURE; 355579dd8a934c684f2e2a34d9aa2f67953320428acUtkarsh Sanghi } 356579dd8a934c684f2e2a34d9aa2f67953320428acUtkarsh Sanghi TPM_HANDLE pcr_handle = HR_PCR + pcr_index; 357579dd8a934c684f2e2a34d9aa2f67953320428acUtkarsh Sanghi std::string pcr_name = NameFromHandle(pcr_handle); 358579dd8a934c684f2e2a34d9aa2f67953320428acUtkarsh Sanghi TPML_DIGEST_VALUES digests; 359579dd8a934c684f2e2a34d9aa2f67953320428acUtkarsh Sanghi digests.count = 1; 360579dd8a934c684f2e2a34d9aa2f67953320428acUtkarsh Sanghi digests.digests[0].hash_alg = TPM_ALG_SHA256; 3614dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn crypto::SHA256HashString(extend_data, digests.digests[0].digest.sha256, 362579dd8a934c684f2e2a34d9aa2f67953320428acUtkarsh Sanghi crypto::kSHA256Length); 363b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn std::unique_ptr<AuthorizationDelegate> empty_password_delegate = 364b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn factory_.GetPasswordAuthorization(""); 365b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn if (!delegate) { 366b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn delegate = empty_password_delegate.get(); 367b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn } 3684dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn return factory_.GetTpm()->PCR_ExtendSync(pcr_handle, pcr_name, digests, 3698b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi delegate); 370579dd8a934c684f2e2a34d9aa2f67953320428acUtkarsh Sanghi} 371579dd8a934c684f2e2a34d9aa2f67953320428acUtkarsh Sanghi 372579dd8a934c684f2e2a34d9aa2f67953320428acUtkarsh SanghiTPM_RC TpmUtilityImpl::ReadPCR(int pcr_index, std::string* pcr_value) { 373579dd8a934c684f2e2a34d9aa2f67953320428acUtkarsh Sanghi TPML_PCR_SELECTION pcr_select_in; 374579dd8a934c684f2e2a34d9aa2f67953320428acUtkarsh Sanghi uint32_t pcr_update_counter; 375579dd8a934c684f2e2a34d9aa2f67953320428acUtkarsh Sanghi TPML_PCR_SELECTION pcr_select_out; 376579dd8a934c684f2e2a34d9aa2f67953320428acUtkarsh Sanghi TPML_DIGEST pcr_values; 377579dd8a934c684f2e2a34d9aa2f67953320428acUtkarsh Sanghi // This process of selecting pcrs is highlighted in TPM 2.0 Library Spec 378579dd8a934c684f2e2a34d9aa2f67953320428acUtkarsh Sanghi // Part 2 (Section 10.5 - PCR structures). 379579dd8a934c684f2e2a34d9aa2f67953320428acUtkarsh Sanghi uint8_t pcr_select_index = pcr_index / 8; 380579dd8a934c684f2e2a34d9aa2f67953320428acUtkarsh Sanghi uint8_t pcr_select_byte = 1 << (pcr_index % 8); 381579dd8a934c684f2e2a34d9aa2f67953320428acUtkarsh Sanghi pcr_select_in.count = 1; 382579dd8a934c684f2e2a34d9aa2f67953320428acUtkarsh Sanghi pcr_select_in.pcr_selections[0].hash = TPM_ALG_SHA256; 383e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi pcr_select_in.pcr_selections[0].sizeof_select = PCR_SELECT_MIN; 384579dd8a934c684f2e2a34d9aa2f67953320428acUtkarsh Sanghi pcr_select_in.pcr_selections[0].pcr_select[pcr_select_index] = 385579dd8a934c684f2e2a34d9aa2f67953320428acUtkarsh Sanghi pcr_select_byte; 386579dd8a934c684f2e2a34d9aa2f67953320428acUtkarsh Sanghi 3874dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn TPM_RC rc = 3884dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn factory_.GetTpm()->PCR_ReadSync(pcr_select_in, &pcr_update_counter, 3894dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn &pcr_select_out, &pcr_values, nullptr); 390579dd8a934c684f2e2a34d9aa2f67953320428acUtkarsh Sanghi if (rc) { 391b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(INFO) << __func__ 392b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Error trying to read a pcr: " << GetErrorString(rc); 393579dd8a934c684f2e2a34d9aa2f67953320428acUtkarsh Sanghi return rc; 394579dd8a934c684f2e2a34d9aa2f67953320428acUtkarsh Sanghi } 395579dd8a934c684f2e2a34d9aa2f67953320428acUtkarsh Sanghi if (pcr_select_out.count != 1 || 3964dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn pcr_select_out.pcr_selections[0].sizeof_select < (pcr_select_index + 1) || 397579dd8a934c684f2e2a34d9aa2f67953320428acUtkarsh Sanghi pcr_select_out.pcr_selections[0].pcr_select[pcr_select_index] != 3984dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn pcr_select_byte) { 399b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": TPM did not return the requested PCR"; 400579dd8a934c684f2e2a34d9aa2f67953320428acUtkarsh Sanghi return TPM_RC_FAILURE; 401579dd8a934c684f2e2a34d9aa2f67953320428acUtkarsh Sanghi } 40235af244e7cf856a02e46ec8f186f36c53582757dUtkarsh Sanghi CHECK_GE(pcr_values.count, 1U); 403579dd8a934c684f2e2a34d9aa2f67953320428acUtkarsh Sanghi pcr_value->assign(StringFrom_TPM2B_DIGEST(pcr_values.digests[0])); 404579dd8a934c684f2e2a34d9aa2f67953320428acUtkarsh Sanghi return TPM_RC_SUCCESS; 405579dd8a934c684f2e2a34d9aa2f67953320428acUtkarsh Sanghi} 406579dd8a934c684f2e2a34d9aa2f67953320428acUtkarsh Sanghi 407b3ba5e0b579a5462c7137cf49b49cc9a78d87944Utkarsh SanghiTPM_RC TpmUtilityImpl::AsymmetricEncrypt(TPM_HANDLE key_handle, 408b3ba5e0b579a5462c7137cf49b49cc9a78d87944Utkarsh Sanghi TPM_ALG_ID scheme, 4099dc77fecdb2446da134b9b2901173bb4dcf5e5e4Utkarsh Sanghi TPM_ALG_ID hash_alg, 410b3ba5e0b579a5462c7137cf49b49cc9a78d87944Utkarsh Sanghi const std::string& plaintext, 4115d3b9451ae2e912aefed0669dd50b2a777ea0ab2Utkarsh Sanghi AuthorizationDelegate* delegate, 412b3ba5e0b579a5462c7137cf49b49cc9a78d87944Utkarsh Sanghi std::string* ciphertext) { 4139dc77fecdb2446da134b9b2901173bb4dcf5e5e4Utkarsh Sanghi TPMT_RSA_DECRYPT in_scheme; 4149dc77fecdb2446da134b9b2901173bb4dcf5e5e4Utkarsh Sanghi if (hash_alg == TPM_ALG_NULL) { 415e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi hash_alg = TPM_ALG_SHA256; 4169dc77fecdb2446da134b9b2901173bb4dcf5e5e4Utkarsh Sanghi } 4179dc77fecdb2446da134b9b2901173bb4dcf5e5e4Utkarsh Sanghi if (scheme == TPM_ALG_RSAES) { 4189dc77fecdb2446da134b9b2901173bb4dcf5e5e4Utkarsh Sanghi in_scheme.scheme = TPM_ALG_RSAES; 4199dc77fecdb2446da134b9b2901173bb4dcf5e5e4Utkarsh Sanghi } else if (scheme == TPM_ALG_OAEP || scheme == TPM_ALG_NULL) { 4209dc77fecdb2446da134b9b2901173bb4dcf5e5e4Utkarsh Sanghi in_scheme.scheme = TPM_ALG_OAEP; 421e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi in_scheme.details.oaep.hash_alg = hash_alg; 4229dc77fecdb2446da134b9b2901173bb4dcf5e5e4Utkarsh Sanghi } else { 423b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Invalid Signing scheme used."; 4249dc77fecdb2446da134b9b2901173bb4dcf5e5e4Utkarsh Sanghi return SAPI_RC_BAD_PARAMETER; 4259dc77fecdb2446da134b9b2901173bb4dcf5e5e4Utkarsh Sanghi } 4269dc77fecdb2446da134b9b2901173bb4dcf5e5e4Utkarsh Sanghi 4278b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi TPMT_PUBLIC public_area; 4288b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi TPM_RC result = GetKeyPublicArea(key_handle, &public_area); 4298b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 430b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Error finding public area for: " << key_handle; 4318b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi return result; 4328b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi } else if (public_area.type != TPM_ALG_RSA) { 433b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Key handle given is not an RSA key"; 434b3ba5e0b579a5462c7137cf49b49cc9a78d87944Utkarsh Sanghi return SAPI_RC_BAD_PARAMETER; 4358b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi } else if ((public_area.object_attributes & kDecrypt) == 0) { 436b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Key handle given is not a decryption key"; 437b3ba5e0b579a5462c7137cf49b49cc9a78d87944Utkarsh Sanghi return SAPI_RC_BAD_PARAMETER; 438b3ba5e0b579a5462c7137cf49b49cc9a78d87944Utkarsh Sanghi } 4398b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi if ((public_area.object_attributes & kRestricted) != 0) { 440b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 441b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Cannot use RSAES for encryption with a restricted key"; 442b3ba5e0b579a5462c7137cf49b49cc9a78d87944Utkarsh Sanghi return SAPI_RC_BAD_PARAMETER; 443b3ba5e0b579a5462c7137cf49b49cc9a78d87944Utkarsh Sanghi } 444b3ba5e0b579a5462c7137cf49b49cc9a78d87944Utkarsh Sanghi std::string key_name; 4458b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi result = ComputeKeyName(public_area, &key_name); 4468b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 447b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Error computing key name for: " << key_handle; 4488b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi return result; 4498b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi } 450b3ba5e0b579a5462c7137cf49b49cc9a78d87944Utkarsh Sanghi 451b3ba5e0b579a5462c7137cf49b49cc9a78d87944Utkarsh Sanghi TPM2B_DATA label; 452b3ba5e0b579a5462c7137cf49b49cc9a78d87944Utkarsh Sanghi label.size = 0; 453b3ba5e0b579a5462c7137cf49b49cc9a78d87944Utkarsh Sanghi TPM2B_PUBLIC_KEY_RSA in_message = Make_TPM2B_PUBLIC_KEY_RSA(plaintext); 454b3ba5e0b579a5462c7137cf49b49cc9a78d87944Utkarsh Sanghi TPM2B_PUBLIC_KEY_RSA out_message; 4554dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn result = factory_.GetTpm()->RSA_EncryptSync(key_handle, key_name, in_message, 4564dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn in_scheme, label, &out_message, 4578b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi delegate); 4588b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 459b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 460b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Error performing RSA encrypt: " << GetErrorString(result); 4618b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi return result; 462b3ba5e0b579a5462c7137cf49b49cc9a78d87944Utkarsh Sanghi } 463b3ba5e0b579a5462c7137cf49b49cc9a78d87944Utkarsh Sanghi ciphertext->assign(StringFrom_TPM2B_PUBLIC_KEY_RSA(out_message)); 464b3ba5e0b579a5462c7137cf49b49cc9a78d87944Utkarsh Sanghi return TPM_RC_SUCCESS; 465b3ba5e0b579a5462c7137cf49b49cc9a78d87944Utkarsh Sanghi} 466b3ba5e0b579a5462c7137cf49b49cc9a78d87944Utkarsh Sanghi 467b3ba5e0b579a5462c7137cf49b49cc9a78d87944Utkarsh SanghiTPM_RC TpmUtilityImpl::AsymmetricDecrypt(TPM_HANDLE key_handle, 468b3ba5e0b579a5462c7137cf49b49cc9a78d87944Utkarsh Sanghi TPM_ALG_ID scheme, 4699dc77fecdb2446da134b9b2901173bb4dcf5e5e4Utkarsh Sanghi TPM_ALG_ID hash_alg, 470b3ba5e0b579a5462c7137cf49b49cc9a78d87944Utkarsh Sanghi const std::string& ciphertext, 4715d3b9451ae2e912aefed0669dd50b2a777ea0ab2Utkarsh Sanghi AuthorizationDelegate* delegate, 472b3ba5e0b579a5462c7137cf49b49cc9a78d87944Utkarsh Sanghi std::string* plaintext) { 4739dc77fecdb2446da134b9b2901173bb4dcf5e5e4Utkarsh Sanghi TPMT_RSA_DECRYPT in_scheme; 4749dc77fecdb2446da134b9b2901173bb4dcf5e5e4Utkarsh Sanghi if (hash_alg == TPM_ALG_NULL) { 475e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi hash_alg = TPM_ALG_SHA256; 4769dc77fecdb2446da134b9b2901173bb4dcf5e5e4Utkarsh Sanghi } 4779dc77fecdb2446da134b9b2901173bb4dcf5e5e4Utkarsh Sanghi if (scheme == TPM_ALG_RSAES) { 4789dc77fecdb2446da134b9b2901173bb4dcf5e5e4Utkarsh Sanghi in_scheme.scheme = TPM_ALG_RSAES; 4799dc77fecdb2446da134b9b2901173bb4dcf5e5e4Utkarsh Sanghi } else if (scheme == TPM_ALG_OAEP || scheme == TPM_ALG_NULL) { 4809dc77fecdb2446da134b9b2901173bb4dcf5e5e4Utkarsh Sanghi in_scheme.scheme = TPM_ALG_OAEP; 481e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi in_scheme.details.oaep.hash_alg = hash_alg; 4829dc77fecdb2446da134b9b2901173bb4dcf5e5e4Utkarsh Sanghi } else { 483b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Invalid Signing scheme used."; 4849dc77fecdb2446da134b9b2901173bb4dcf5e5e4Utkarsh Sanghi return SAPI_RC_BAD_PARAMETER; 4859dc77fecdb2446da134b9b2901173bb4dcf5e5e4Utkarsh Sanghi } 4861ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi TPM_RC result; 487c04decde2a6e9b74395f402818852e752534254bUtkarsh Sanghi if (delegate == nullptr) { 4881ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi result = SAPI_RC_INVALID_SESSIONS; 489b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 490b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": This method needs a valid authorization delegate: " 4911ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi << GetErrorString(result); 4921ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi return result; 4931ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi } 4948b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi TPMT_PUBLIC public_area; 4951ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi result = GetKeyPublicArea(key_handle, &public_area); 4961ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi if (result) { 497b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Error finding public area for: " << key_handle; 4981ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi return result; 4998b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi } else if (public_area.type != TPM_ALG_RSA) { 500b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Key handle given is not an RSA key"; 501b3ba5e0b579a5462c7137cf49b49cc9a78d87944Utkarsh Sanghi return SAPI_RC_BAD_PARAMETER; 5028b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi } else if ((public_area.object_attributes & kDecrypt) == 0) { 503b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Key handle given is not a decryption key"; 504b3ba5e0b579a5462c7137cf49b49cc9a78d87944Utkarsh Sanghi return SAPI_RC_BAD_PARAMETER; 505b3ba5e0b579a5462c7137cf49b49cc9a78d87944Utkarsh Sanghi } 5068b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi if ((public_area.object_attributes & kRestricted) != 0) { 507b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 508b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Cannot use RSAES for encryption with a restricted key"; 509b3ba5e0b579a5462c7137cf49b49cc9a78d87944Utkarsh Sanghi return SAPI_RC_BAD_PARAMETER; 510b3ba5e0b579a5462c7137cf49b49cc9a78d87944Utkarsh Sanghi } 511b3ba5e0b579a5462c7137cf49b49cc9a78d87944Utkarsh Sanghi std::string key_name; 5128b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi result = ComputeKeyName(public_area, &key_name); 5131ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi if (result) { 514b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Error computing key name for: " << key_handle; 5151ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi return result; 516b3ba5e0b579a5462c7137cf49b49cc9a78d87944Utkarsh Sanghi } 517b3ba5e0b579a5462c7137cf49b49cc9a78d87944Utkarsh Sanghi 518b3ba5e0b579a5462c7137cf49b49cc9a78d87944Utkarsh Sanghi TPM2B_DATA label; 519b3ba5e0b579a5462c7137cf49b49cc9a78d87944Utkarsh Sanghi label.size = 0; 520b3ba5e0b579a5462c7137cf49b49cc9a78d87944Utkarsh Sanghi TPM2B_PUBLIC_KEY_RSA in_message = Make_TPM2B_PUBLIC_KEY_RSA(ciphertext); 521b3ba5e0b579a5462c7137cf49b49cc9a78d87944Utkarsh Sanghi TPM2B_PUBLIC_KEY_RSA out_message; 5224dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn result = factory_.GetTpm()->RSA_DecryptSync(key_handle, key_name, in_message, 5234dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn in_scheme, label, &out_message, 5245d3b9451ae2e912aefed0669dd50b2a777ea0ab2Utkarsh Sanghi delegate); 5251ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi if (result) { 526b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 527b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Error performing RSA decrypt: " << GetErrorString(result); 5281ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi return result; 529b3ba5e0b579a5462c7137cf49b49cc9a78d87944Utkarsh Sanghi } 530b3ba5e0b579a5462c7137cf49b49cc9a78d87944Utkarsh Sanghi plaintext->assign(StringFrom_TPM2B_PUBLIC_KEY_RSA(out_message)); 531b3ba5e0b579a5462c7137cf49b49cc9a78d87944Utkarsh Sanghi return TPM_RC_SUCCESS; 532b3ba5e0b579a5462c7137cf49b49cc9a78d87944Utkarsh Sanghi} 533b3ba5e0b579a5462c7137cf49b49cc9a78d87944Utkarsh Sanghi 534748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh SanghiTPM_RC TpmUtilityImpl::Sign(TPM_HANDLE key_handle, 535748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi TPM_ALG_ID scheme, 536748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi TPM_ALG_ID hash_alg, 537887ccbcc4db5fa0b5221018296aa49b86a5ac26fUtkarsh Sanghi const std::string& plaintext, 5385d3b9451ae2e912aefed0669dd50b2a777ea0ab2Utkarsh Sanghi AuthorizationDelegate* delegate, 539748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi std::string* signature) { 540748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi TPMT_SIG_SCHEME in_scheme; 541748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi if (hash_alg == TPM_ALG_NULL) { 542e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi hash_alg = TPM_ALG_SHA256; 543e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi } 544748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi if (scheme == TPM_ALG_RSAPSS) { 545748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi in_scheme.scheme = TPM_ALG_RSAPSS; 546e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi in_scheme.details.rsapss.hash_alg = hash_alg; 547748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi } else if (scheme == TPM_ALG_RSASSA || scheme == TPM_ALG_NULL) { 548748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi in_scheme.scheme = TPM_ALG_RSASSA; 549e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi in_scheme.details.rsassa.hash_alg = hash_alg; 550748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi } else { 551b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Invalid Signing scheme used."; 552748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi return SAPI_RC_BAD_PARAMETER; 553748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi } 5541ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi TPM_RC result; 555c04decde2a6e9b74395f402818852e752534254bUtkarsh Sanghi if (delegate == nullptr) { 5561ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi result = SAPI_RC_INVALID_SESSIONS; 557b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 558b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": This method needs a valid authorization delegate: " 5591ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi << GetErrorString(result); 5601ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi return result; 5611ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi } 5628b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi TPMT_PUBLIC public_area; 5631ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi result = GetKeyPublicArea(key_handle, &public_area); 5641ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi if (result) { 565b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Error finding public area for: " << key_handle; 5661ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi return result; 5678b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi } else if (public_area.type != TPM_ALG_RSA) { 568b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Key handle given is not an RSA key"; 569748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi return SAPI_RC_BAD_PARAMETER; 5708b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi } else if ((public_area.object_attributes & kSign) == 0) { 571b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Key handle given is not a signging key"; 572748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi return SAPI_RC_BAD_PARAMETER; 5738b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi } else if ((public_area.object_attributes & kRestricted) != 0) { 574b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Key handle references a restricted key"; 575748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi return SAPI_RC_BAD_PARAMETER; 576748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi } 577748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi 578748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi std::string key_name; 5798b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi result = ComputeKeyName(public_area, &key_name); 5801ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi if (result) { 581b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Error computing key name for: " << key_handle; 5821ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi return result; 583748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi } 584887ccbcc4db5fa0b5221018296aa49b86a5ac26fUtkarsh Sanghi std::string digest = HashString(plaintext, hash_alg); 585748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi TPM2B_DIGEST tpm_digest = Make_TPM2B_DIGEST(digest); 586748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi TPMT_SIGNATURE signature_out; 587748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi TPMT_TK_HASHCHECK validation; 588748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi validation.tag = TPM_ST_HASHCHECK; 589e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi validation.hierarchy = TPM_RH_NULL; 590748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi validation.digest.size = 0; 5914dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn result = 5924dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn factory_.GetTpm()->SignSync(key_handle, key_name, tpm_digest, in_scheme, 5934dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn validation, &signature_out, delegate); 5941ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi if (result) { 595b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 596b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Error signing digest: " << GetErrorString(result); 5971ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi return result; 598748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi } 599748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi if (scheme == TPM_ALG_RSAPSS) { 600748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi signature->resize(signature_out.signature.rsapss.sig.size); 6014dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn signature->assign( 6024dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn StringFrom_TPM2B_PUBLIC_KEY_RSA(signature_out.signature.rsapss.sig)); 603748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi } else { 604748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi signature->resize(signature_out.signature.rsassa.sig.size); 6054dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn signature->assign( 6064dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn StringFrom_TPM2B_PUBLIC_KEY_RSA(signature_out.signature.rsassa.sig)); 607748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi } 608748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi return TPM_RC_SUCCESS; 609748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi} 610748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi 611748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh SanghiTPM_RC TpmUtilityImpl::Verify(TPM_HANDLE key_handle, 612748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi TPM_ALG_ID scheme, 613748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi TPM_ALG_ID hash_alg, 614887ccbcc4db5fa0b5221018296aa49b86a5ac26fUtkarsh Sanghi const std::string& plaintext, 6156f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi const std::string& signature, 6166f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi AuthorizationDelegate* delegate) { 6178b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi TPMT_PUBLIC public_area; 618748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi TPM_RC return_code = GetKeyPublicArea(key_handle, &public_area); 619748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi if (return_code) { 620b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Error finding public area for: " << key_handle; 621748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi return return_code; 6228b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi } else if (public_area.type != TPM_ALG_RSA) { 623b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Key handle given is not an RSA key"; 624748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi return SAPI_RC_BAD_PARAMETER; 6258b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi } else if ((public_area.object_attributes & kSign) == 0) { 626b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Key handle given is not a signing key"; 627748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi return SAPI_RC_BAD_PARAMETER; 6288b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi } else if ((public_area.object_attributes & kRestricted) != 0) { 629b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 630b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Cannot use RSAPSS for signing with a restricted key"; 631748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi return SAPI_RC_BAD_PARAMETER; 632748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi } 633748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi if (hash_alg == TPM_ALG_NULL) { 634e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi hash_alg = TPM_ALG_SHA256; 635e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi } 636e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi 637e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi TPMT_SIGNATURE signature_in; 638748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi if (scheme == TPM_ALG_RSAPSS) { 639748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi signature_in.sig_alg = TPM_ALG_RSAPSS; 640e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi signature_in.signature.rsapss.hash = hash_alg; 641748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi signature_in.signature.rsapss.sig = Make_TPM2B_PUBLIC_KEY_RSA(signature); 642748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi } else if (scheme == TPM_ALG_NULL || scheme == TPM_ALG_RSASSA) { 643748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi signature_in.sig_alg = TPM_ALG_RSASSA; 644e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi signature_in.signature.rsassa.hash = hash_alg; 645748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi signature_in.signature.rsassa.sig = Make_TPM2B_PUBLIC_KEY_RSA(signature); 646748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi } else { 647b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Invalid scheme used to verify signature."; 648748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi return SAPI_RC_BAD_PARAMETER; 649748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi } 650748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi std::string key_name; 651748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi TPMT_TK_VERIFIED verified; 652887ccbcc4db5fa0b5221018296aa49b86a5ac26fUtkarsh Sanghi std::string digest = HashString(plaintext, hash_alg); 653748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi TPM2B_DIGEST tpm_digest = Make_TPM2B_DIGEST(digest); 6544dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn return_code = factory_.GetTpm()->VerifySignatureSync( 6554dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn key_handle, key_name, tpm_digest, signature_in, &verified, delegate); 656748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi if (return_code == TPM_RC_SIGNATURE) { 657b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(WARNING) << __func__ << ": Incorrect signature for given digest."; 658748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi return TPM_RC_SIGNATURE; 659748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi } else if (return_code && return_code != TPM_RC_SIGNATURE) { 660b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Error verifying signature: " 661b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << GetErrorString(return_code); 662748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi return return_code; 663748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi } 664748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi return TPM_RC_SUCCESS; 665748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi} 666748f7d68284813a78b883f9c05988f6de535fc8aUtkarsh Sanghi 667fded77411da5ef66dff7389e49f40900c19d510cUtkarsh SanghiTPM_RC TpmUtilityImpl::CertifyCreation(TPM_HANDLE key_handle, 668fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi const std::string& creation_blob) { 669fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi TPM2B_CREATION_DATA creation_data; 670fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi TPM2B_DIGEST creation_hash; 671fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi TPMT_TK_CREATION creation_ticket; 6724dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn if (!factory_.GetBlobParser()->ParseCreationBlob( 6734dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn creation_blob, &creation_data, &creation_hash, &creation_ticket)) { 674b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Error parsing CreationBlob."; 675fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi return SAPI_RC_BAD_PARAMETER; 676fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi } 677fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi TPM2B_DATA qualifying_data; 678fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi qualifying_data.size = 0; 679fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi TPMT_SIG_SCHEME in_scheme; 680fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi in_scheme.scheme = TPM_ALG_NULL; 681fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi TPM2B_ATTEST certify_info; 682fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi TPMT_SIGNATURE signature; 68330c921db09d27768acc1ea0d8b6a9c8e814f931aLuis Hector Chavez std::unique_ptr<AuthorizationDelegate> delegate = 684fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi factory_.GetPasswordAuthorization(""); 6854dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn TPM_RC result = factory_.GetTpm()->CertifyCreationSync( 6864dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn TPM_RH_NULL, "", key_handle, "", qualifying_data, creation_hash, 6874dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn in_scheme, creation_ticket, &certify_info, &signature, delegate.get()); 688fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi if (result != TPM_RC_SUCCESS) { 689b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 690b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Error certifying key creation: " << GetErrorString(result); 691fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi return result; 692fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi } 693fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi return TPM_RC_SUCCESS; 694fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi} 695fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi 69633ca033c9665b8496f3491037403ae1574a54227Utkarsh SanghiTPM_RC TpmUtilityImpl::ChangeKeyAuthorizationData( 69733ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi TPM_HANDLE key_handle, 69833ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi const std::string& new_password, 6995d3b9451ae2e912aefed0669dd50b2a777ea0ab2Utkarsh Sanghi AuthorizationDelegate* delegate, 70033ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi std::string* key_blob) { 7011ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi TPM_RC result; 702c04decde2a6e9b74395f402818852e752534254bUtkarsh Sanghi if (delegate == nullptr) { 7031ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi result = SAPI_RC_INVALID_SESSIONS; 704b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 705b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": This method needs a valid authorization delegate: " 7061ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi << GetErrorString(result); 7071ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi return result; 7081ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi } 70933ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi std::string key_name; 71033ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi std::string parent_name; 7111ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi result = GetKeyName(key_handle, &key_name); 71233ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 713b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Error getting Key name for key_handle: " 71433ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi << GetErrorString(result); 71533ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi return result; 71633ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi } 71733ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi result = GetKeyName(kRSAStorageRootKey, &parent_name); 71833ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 719b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Error getting Key name for RSA-SRK: " 72033ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi << GetErrorString(result); 72133ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi return result; 72233ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi } 72333ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi TPM2B_AUTH new_auth = Make_TPM2B_DIGEST(new_password); 72433ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi TPM2B_PRIVATE new_private_data; 72533ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi new_private_data.size = 0; 7264dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn result = factory_.GetTpm()->ObjectChangeAuthSync( 7274dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn key_handle, key_name, kRSAStorageRootKey, parent_name, new_auth, 7284dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn &new_private_data, delegate); 72933ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 730b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Error changing object authorization data: " 73133ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi << GetErrorString(result); 73233ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi return result; 73333ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi } 73433ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi if (key_blob) { 7358b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi TPMT_PUBLIC public_data; 73633ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi result = GetKeyPublicArea(key_handle, &public_data); 73733ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 73833ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi return result; 73933ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi } 7400ebbc58fe6d45378a5b502c33eb1c4289fd8b05bUtkarsh Sanghi if (!factory_.GetBlobParser()->SerializeKeyBlob( 7414dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn Make_TPM2B_PUBLIC(public_data), new_private_data, key_blob)) { 7420ebbc58fe6d45378a5b502c33eb1c4289fd8b05bUtkarsh Sanghi return SAPI_RC_BAD_TCTI_STRUCTURE; 74333ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi } 74433ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi } 74533ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi return TPM_RC_SUCCESS; 74633ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi} 74733ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi 74833ca033c9665b8496f3491037403ae1574a54227Utkarsh SanghiTPM_RC TpmUtilityImpl::ImportRSAKey(AsymmetricKeyUsage key_type, 74933ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi const std::string& modulus, 75033ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi uint32_t public_exponent, 75133ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi const std::string& prime_factor, 75233ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi const std::string& password, 7535d3b9451ae2e912aefed0669dd50b2a777ea0ab2Utkarsh Sanghi AuthorizationDelegate* delegate, 75433ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi std::string* key_blob) { 7551ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi TPM_RC result; 756c04decde2a6e9b74395f402818852e752534254bUtkarsh Sanghi if (delegate == nullptr) { 7571ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi result = SAPI_RC_INVALID_SESSIONS; 758b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 759b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": This method needs a valid authorization delegate: " 7601ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi << GetErrorString(result); 7611ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi return result; 7621ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi } 76333ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi std::string parent_name; 7641ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi result = GetKeyName(kRSAStorageRootKey, &parent_name); 76533ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 766b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Error getting Key name for RSA-SRK: " 76733ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi << GetErrorString(result); 76833ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi return result; 76933ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi } 77033ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi TPMT_PUBLIC public_area = CreateDefaultPublicArea(TPM_ALG_RSA); 77133ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi public_area.object_attributes = kUserWithAuth | kNoDA; 77233ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi switch (key_type) { 77333ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi case AsymmetricKeyUsage::kDecryptKey: 77433ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi public_area.object_attributes |= kDecrypt; 77533ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi break; 77633ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi case AsymmetricKeyUsage::kSignKey: 77733ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi public_area.object_attributes |= kSign; 77833ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi break; 77933ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi case AsymmetricKeyUsage::kDecryptAndSignKey: 78033ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi public_area.object_attributes |= (kSign | kDecrypt); 78133ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi break; 78233ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi } 78333ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi public_area.parameters.rsa_detail.key_bits = modulus.size() * 8; 78433ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi public_area.parameters.rsa_detail.exponent = public_exponent; 78533ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi public_area.unique.rsa = Make_TPM2B_PUBLIC_KEY_RSA(modulus); 78633ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi TPM2B_DATA encryption_key; 78733ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi encryption_key.size = kAesKeySize; 7884dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn CHECK_EQ(RAND_bytes(encryption_key.buffer, encryption_key.size), 1) 7894dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn << "Error generating a cryptographically random Aes Key."; 79033ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi TPM2B_PUBLIC public_data = Make_TPM2B_PUBLIC(public_area); 79133ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi TPM2B_ENCRYPTED_SECRET in_sym_seed = Make_TPM2B_ENCRYPTED_SECRET(""); 79233ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi TPMT_SYM_DEF_OBJECT symmetric_alg; 79333ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi symmetric_alg.algorithm = TPM_ALG_AES; 79433ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi symmetric_alg.key_bits.aes = kAesKeySize * 8; 79533ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi symmetric_alg.mode.aes = TPM_ALG_CFB; 79633ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi TPMT_SENSITIVE in_sensitive; 79733ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi in_sensitive.sensitive_type = TPM_ALG_RSA; 79833ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi in_sensitive.auth_value = Make_TPM2B_DIGEST(password); 79933ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi in_sensitive.seed_value = Make_TPM2B_DIGEST(""); 80033ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi in_sensitive.sensitive.rsa = Make_TPM2B_PRIVATE_KEY_RSA(prime_factor); 80133ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi TPM2B_PRIVATE private_data; 8024dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn result = EncryptPrivateData(in_sensitive, public_area, &private_data, 8034dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn &encryption_key); 80433ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 805b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Error creating encrypted private struct: " 80633ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi << GetErrorString(result); 80733ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi return result; 80833ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi } 80933ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi TPM2B_PRIVATE tpm_private_data; 81033ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi tpm_private_data.size = 0; 8114dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn result = factory_.GetTpm()->ImportSync( 8124dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn kRSAStorageRootKey, parent_name, encryption_key, public_data, 8134dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn private_data, in_sym_seed, symmetric_alg, &tpm_private_data, delegate); 81433ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 815b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 816b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Error importing key: " << GetErrorString(result); 81733ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi return result; 81833ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi } 81933ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi if (key_blob) { 8200ebbc58fe6d45378a5b502c33eb1c4289fd8b05bUtkarsh Sanghi if (!factory_.GetBlobParser()->SerializeKeyBlob( 8214dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn public_data, tpm_private_data, key_blob)) { 8220ebbc58fe6d45378a5b502c33eb1c4289fd8b05bUtkarsh Sanghi return SAPI_RC_BAD_TCTI_STRUCTURE; 82333ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi } 82433ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi } 82533ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi return TPM_RC_SUCCESS; 82633ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi} 82733ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi 8286465502c740d2599d95e09232c744f6d2ed54505Utkarsh SanghiTPM_RC TpmUtilityImpl::CreateRSAKeyPair(AsymmetricKeyUsage key_type, 8296465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi int modulus_bits, 8306465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi uint32_t public_exponent, 8316465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi const std::string& password, 832fc942a5ffc967b7b2b206aee8b91b3bae1933382Utkarsh Sanghi const std::string& policy_digest, 8336ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi bool use_only_policy_authorization, 8340ebbc58fe6d45378a5b502c33eb1c4289fd8b05bUtkarsh Sanghi int creation_pcr_index, 8355d3b9451ae2e912aefed0669dd50b2a777ea0ab2Utkarsh Sanghi AuthorizationDelegate* delegate, 836a5a2f2ea49e0085bf8d7f6f2b6e7cd624d710c01Utkarsh Sanghi std::string* key_blob, 837a5a2f2ea49e0085bf8d7f6f2b6e7cd624d710c01Utkarsh Sanghi std::string* creation_blob) { 8386465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi CHECK(key_blob); 8391ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi TPM_RC result; 840c04decde2a6e9b74395f402818852e752534254bUtkarsh Sanghi if (delegate == nullptr) { 8411ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi result = SAPI_RC_INVALID_SESSIONS; 842b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 843b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": This method needs a valid authorization delegate: " 8441ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi << GetErrorString(result); 8451ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi return result; 8461ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi } 84782b03cf80cbe7ab5d5edb2cb46d245721e993a68Utkarsh Sanghi std::string parent_name; 8481ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi result = GetKeyName(kRSAStorageRootKey, &parent_name); 8496465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 850b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Error getting Key name for RSA-SRK: " 8516465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi << GetErrorString(result); 8526465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi return result; 85382b03cf80cbe7ab5d5edb2cb46d245721e993a68Utkarsh Sanghi } 8542ee32a9d61896f544d87ecee24dc25cc33c9ebb3Utkarsh Sanghi TPMT_PUBLIC public_area = CreateDefaultPublicArea(TPM_ALG_RSA); 855fc942a5ffc967b7b2b206aee8b91b3bae1933382Utkarsh Sanghi public_area.auth_policy = Make_TPM2B_DIGEST(policy_digest); 8562ee32a9d61896f544d87ecee24dc25cc33c9ebb3Utkarsh Sanghi public_area.object_attributes |= 8572ee32a9d61896f544d87ecee24dc25cc33c9ebb3Utkarsh Sanghi (kSensitiveDataOrigin | kUserWithAuth | kNoDA); 85882b03cf80cbe7ab5d5edb2cb46d245721e993a68Utkarsh Sanghi switch (key_type) { 85982b03cf80cbe7ab5d5edb2cb46d245721e993a68Utkarsh Sanghi case AsymmetricKeyUsage::kDecryptKey: 860e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi public_area.object_attributes |= kDecrypt; 86182b03cf80cbe7ab5d5edb2cb46d245721e993a68Utkarsh Sanghi break; 86282b03cf80cbe7ab5d5edb2cb46d245721e993a68Utkarsh Sanghi case AsymmetricKeyUsage::kSignKey: 863e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi public_area.object_attributes |= kSign; 86482b03cf80cbe7ab5d5edb2cb46d245721e993a68Utkarsh Sanghi break; 86582b03cf80cbe7ab5d5edb2cb46d245721e993a68Utkarsh Sanghi case AsymmetricKeyUsage::kDecryptAndSignKey: 866e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi public_area.object_attributes |= (kSign | kDecrypt); 86782b03cf80cbe7ab5d5edb2cb46d245721e993a68Utkarsh Sanghi break; 86882b03cf80cbe7ab5d5edb2cb46d245721e993a68Utkarsh Sanghi } 8696ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi if (use_only_policy_authorization && !policy_digest.empty()) { 8706ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi public_area.object_attributes |= kAdminWithPolicy; 8716ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi public_area.object_attributes &= (~kUserWithAuth); 8726ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi } 8736465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi public_area.parameters.rsa_detail.key_bits = modulus_bits; 8746465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi public_area.parameters.rsa_detail.exponent = public_exponent; 8750ebbc58fe6d45378a5b502c33eb1c4289fd8b05bUtkarsh Sanghi TPML_PCR_SELECTION creation_pcrs = {}; 8760ebbc58fe6d45378a5b502c33eb1c4289fd8b05bUtkarsh Sanghi if (creation_pcr_index == kNoCreationPCR) { 8770ebbc58fe6d45378a5b502c33eb1c4289fd8b05bUtkarsh Sanghi creation_pcrs.count = 0; 8780ebbc58fe6d45378a5b502c33eb1c4289fd8b05bUtkarsh Sanghi } else if (creation_pcr_index < 0 || 8790ebbc58fe6d45378a5b502c33eb1c4289fd8b05bUtkarsh Sanghi creation_pcr_index > (PCR_SELECT_MIN * 8)) { 880b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 881b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Creation PCR index is not within the allocated bank."; 8820ebbc58fe6d45378a5b502c33eb1c4289fd8b05bUtkarsh Sanghi return SAPI_RC_BAD_PARAMETER; 8830ebbc58fe6d45378a5b502c33eb1c4289fd8b05bUtkarsh Sanghi } else { 8840ebbc58fe6d45378a5b502c33eb1c4289fd8b05bUtkarsh Sanghi creation_pcrs.count = 1; 8850ebbc58fe6d45378a5b502c33eb1c4289fd8b05bUtkarsh Sanghi creation_pcrs.pcr_selections[0].hash = TPM_ALG_SHA256; 8860ebbc58fe6d45378a5b502c33eb1c4289fd8b05bUtkarsh Sanghi creation_pcrs.pcr_selections[0].sizeof_select = PCR_SELECT_MIN; 8870ebbc58fe6d45378a5b502c33eb1c4289fd8b05bUtkarsh Sanghi creation_pcrs.pcr_selections[0].pcr_select[creation_pcr_index / 8] = 8880ebbc58fe6d45378a5b502c33eb1c4289fd8b05bUtkarsh Sanghi 1 << (creation_pcr_index % 8); 8890ebbc58fe6d45378a5b502c33eb1c4289fd8b05bUtkarsh Sanghi } 890e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi TPMS_SENSITIVE_CREATE sensitive; 891e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi sensitive.user_auth = Make_TPM2B_DIGEST(password); 892e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi sensitive.data = Make_TPM2B_SENSITIVE_DATA(""); 8934dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn TPM2B_SENSITIVE_CREATE sensitive_create = 8944dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn Make_TPM2B_SENSITIVE_CREATE(sensitive); 89582b03cf80cbe7ab5d5edb2cb46d245721e993a68Utkarsh Sanghi TPM2B_DATA outside_info = Make_TPM2B_DATA(""); 89682b03cf80cbe7ab5d5edb2cb46d245721e993a68Utkarsh Sanghi TPM2B_PUBLIC out_public; 8976465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi out_public.size = 0; 8986465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi TPM2B_PRIVATE out_private; 8996465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi out_private.size = 0; 90082b03cf80cbe7ab5d5edb2cb46d245721e993a68Utkarsh Sanghi TPM2B_CREATION_DATA creation_data; 90182b03cf80cbe7ab5d5edb2cb46d245721e993a68Utkarsh Sanghi TPM2B_DIGEST creation_hash; 90282b03cf80cbe7ab5d5edb2cb46d245721e993a68Utkarsh Sanghi TPMT_TK_CREATION creation_ticket; 9034dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn result = factory_.GetTpm()->CreateSync( 9044dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn kRSAStorageRootKey, parent_name, sensitive_create, 9054dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn Make_TPM2B_PUBLIC(public_area), outside_info, creation_pcrs, &out_private, 9064dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn &out_public, &creation_data, &creation_hash, &creation_ticket, delegate); 9076465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 908b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 909b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Error creating RSA key: " << GetErrorString(result); 9106465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi return result; 91182b03cf80cbe7ab5d5edb2cb46d245721e993a68Utkarsh Sanghi } 9124dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn if (!factory_.GetBlobParser()->SerializeKeyBlob(out_public, out_private, 9134dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn key_blob)) { 9140ebbc58fe6d45378a5b502c33eb1c4289fd8b05bUtkarsh Sanghi return SAPI_RC_BAD_TCTI_STRUCTURE; 91582b03cf80cbe7ab5d5edb2cb46d245721e993a68Utkarsh Sanghi } 916a5a2f2ea49e0085bf8d7f6f2b6e7cd624d710c01Utkarsh Sanghi if (creation_blob) { 9170ebbc58fe6d45378a5b502c33eb1c4289fd8b05bUtkarsh Sanghi if (!factory_.GetBlobParser()->SerializeCreationBlob( 9184dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn creation_data, creation_hash, creation_ticket, creation_blob)) { 9190ebbc58fe6d45378a5b502c33eb1c4289fd8b05bUtkarsh Sanghi return SAPI_RC_BAD_TCTI_STRUCTURE; 920a5a2f2ea49e0085bf8d7f6f2b6e7cd624d710c01Utkarsh Sanghi } 921a5a2f2ea49e0085bf8d7f6f2b6e7cd624d710c01Utkarsh Sanghi } 92282b03cf80cbe7ab5d5edb2cb46d245721e993a68Utkarsh Sanghi return TPM_RC_SUCCESS; 92382b03cf80cbe7ab5d5edb2cb46d245721e993a68Utkarsh Sanghi} 92482b03cf80cbe7ab5d5edb2cb46d245721e993a68Utkarsh Sanghi 9256465502c740d2599d95e09232c744f6d2ed54505Utkarsh SanghiTPM_RC TpmUtilityImpl::LoadKey(const std::string& key_blob, 9265d3b9451ae2e912aefed0669dd50b2a777ea0ab2Utkarsh Sanghi AuthorizationDelegate* delegate, 9276465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi TPM_HANDLE* key_handle) { 9280ebbc58fe6d45378a5b502c33eb1c4289fd8b05bUtkarsh Sanghi CHECK(key_handle); 9291ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi TPM_RC result; 930c04decde2a6e9b74395f402818852e752534254bUtkarsh Sanghi if (delegate == nullptr) { 9311ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi result = SAPI_RC_INVALID_SESSIONS; 932b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 933b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": This method needs a valid authorization delegate: " 9341ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi << GetErrorString(result); 9351ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi return result; 9361ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi } 9376465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi std::string parent_name; 9381ef82e4a52abc91d0e8db12500c2da0d8c21f62cUtkarsh Sanghi result = GetKeyName(kRSAStorageRootKey, &parent_name); 9396465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 940b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 941b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Error getting parent key name: " << GetErrorString(result); 9426465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi return result; 9436465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi } 9446465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi TPM2B_PUBLIC in_public; 9456465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi TPM2B_PRIVATE in_private; 9464dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn if (!factory_.GetBlobParser()->ParseKeyBlob(key_blob, &in_public, 9474dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn &in_private)) { 9480ebbc58fe6d45378a5b502c33eb1c4289fd8b05bUtkarsh Sanghi return SAPI_RC_BAD_TCTI_STRUCTURE; 9496465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi } 9506465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi TPM2B_NAME key_name; 9516465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi key_name.size = 0; 9524dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn result = 9534dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn factory_.GetTpm()->LoadSync(kRSAStorageRootKey, parent_name, in_private, 9544dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn in_public, key_handle, &key_name, delegate); 9556465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 956b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Error loading key: " << GetErrorString(result); 9576465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi return result; 9586465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi } 9596465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi return TPM_RC_SUCCESS; 9601c4ff198686b6330dd863f872f52e8efd1a94e3dUtkarsh Sanghi} 9611c4ff198686b6330dd863f872f52e8efd1a94e3dUtkarsh Sanghi 9621c4ff198686b6330dd863f872f52e8efd1a94e3dUtkarsh SanghiTPM_RC TpmUtilityImpl::GetKeyName(TPM_HANDLE handle, std::string* name) { 9638b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi CHECK(name); 9648b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi TPM_RC result; 9658b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi TPMT_PUBLIC public_data; 9668b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi result = GetKeyPublicArea(handle, &public_data); 9678b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 968b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 969b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Error fetching public info: " << GetErrorString(result); 9708b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi return result; 9718b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi } 9728b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi result = ComputeKeyName(public_data, name); 9738b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 974b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 975b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Error computing key name: " << GetErrorString(result); 9768b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi return TPM_RC_SUCCESS; 9771c4ff198686b6330dd863f872f52e8efd1a94e3dUtkarsh Sanghi } 9781c4ff198686b6330dd863f872f52e8efd1a94e3dUtkarsh Sanghi return TPM_RC_SUCCESS; 9791c4ff198686b6330dd863f872f52e8efd1a94e3dUtkarsh Sanghi} 9801c4ff198686b6330dd863f872f52e8efd1a94e3dUtkarsh Sanghi 9811c4ff198686b6330dd863f872f52e8efd1a94e3dUtkarsh SanghiTPM_RC TpmUtilityImpl::GetKeyPublicArea(TPM_HANDLE handle, 9828b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi TPMT_PUBLIC* public_data) { 9831c4ff198686b6330dd863f872f52e8efd1a94e3dUtkarsh Sanghi CHECK(public_data); 9841c4ff198686b6330dd863f872f52e8efd1a94e3dUtkarsh Sanghi TPM2B_NAME out_name; 9858b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi TPM2B_PUBLIC public_area; 9861c4ff198686b6330dd863f872f52e8efd1a94e3dUtkarsh Sanghi TPM2B_NAME qualified_name; 9871c4ff198686b6330dd863f872f52e8efd1a94e3dUtkarsh Sanghi std::string handle_name; // Unused 9884dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn TPM_RC return_code = factory_.GetTpm()->ReadPublicSync( 9894dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn handle, handle_name, &public_area, &out_name, &qualified_name, nullptr); 9901c4ff198686b6330dd863f872f52e8efd1a94e3dUtkarsh Sanghi if (return_code) { 991b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 992b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Error getting public area for object: " << handle; 9931c4ff198686b6330dd863f872f52e8efd1a94e3dUtkarsh Sanghi return return_code; 9941c4ff198686b6330dd863f872f52e8efd1a94e3dUtkarsh Sanghi } 9958b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi *public_data = public_area.public_area; 9961c4ff198686b6330dd863f872f52e8efd1a94e3dUtkarsh Sanghi return TPM_RC_SUCCESS; 9971c4ff198686b6330dd863f872f52e8efd1a94e3dUtkarsh Sanghi} 9981c4ff198686b6330dd863f872f52e8efd1a94e3dUtkarsh Sanghi 999a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh SanghiTPM_RC TpmUtilityImpl::SealData(const std::string& data_to_seal, 1000a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi const std::string& policy_digest, 1001a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi AuthorizationDelegate* delegate, 1002a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi std::string* sealed_data) { 1003a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi CHECK(sealed_data); 1004a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi TPM_RC result; 1005a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi if (delegate == nullptr) { 1006a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi result = SAPI_RC_INVALID_SESSIONS; 1007b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 1008b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": This method needs a valid authorization delegate: " 1009a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi << GetErrorString(result); 1010a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi return result; 1011a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi } 1012a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi std::string parent_name; 1013a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi result = GetKeyName(kRSAStorageRootKey, &parent_name); 1014a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 1015b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Error getting Key name for RSA-SRK: " 1016a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi << GetErrorString(result); 1017a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi return result; 1018a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi } 1019a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi // We seal data to the TPM by creating a KEYEDHASH object with sign and 1020a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi // decrypt attributes disabled. 1021a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi TPMT_PUBLIC public_area = CreateDefaultPublicArea(TPM_ALG_KEYEDHASH); 1022a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi public_area.auth_policy = Make_TPM2B_DIGEST(policy_digest); 1023a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi public_area.object_attributes = kAdminWithPolicy | kNoDA; 1024a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi public_area.unique.keyed_hash.size = 0; 1025a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi TPML_PCR_SELECTION creation_pcrs = {}; 1026a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi TPMS_SENSITIVE_CREATE sensitive; 1027a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi sensitive.user_auth = Make_TPM2B_DIGEST(""); 1028a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi sensitive.data = Make_TPM2B_SENSITIVE_DATA(data_to_seal); 10294dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn TPM2B_SENSITIVE_CREATE sensitive_create = 10304dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn Make_TPM2B_SENSITIVE_CREATE(sensitive); 1031a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi TPM2B_DATA outside_info = Make_TPM2B_DATA(""); 1032a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi TPM2B_PUBLIC out_public; 1033a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi out_public.size = 0; 1034a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi TPM2B_PRIVATE out_private; 1035a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi out_private.size = 0; 1036a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi TPM2B_CREATION_DATA creation_data; 1037a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi TPM2B_DIGEST creation_hash; 1038a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi TPMT_TK_CREATION creation_ticket; 10394dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn result = factory_.GetTpm()->CreateSync( 10404dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn kRSAStorageRootKey, parent_name, sensitive_create, 10414dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn Make_TPM2B_PUBLIC(public_area), outside_info, creation_pcrs, &out_private, 10424dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn &out_public, &creation_data, &creation_hash, &creation_ticket, delegate); 1043a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 1044b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 1045b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Error creating sealed object: " << GetErrorString(result); 1046a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi return result; 1047a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi } 10484dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn if (!factory_.GetBlobParser()->SerializeKeyBlob(out_public, out_private, 10494dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn sealed_data)) { 1050a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi return SAPI_RC_BAD_TCTI_STRUCTURE; 1051a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi } 1052a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi return TPM_RC_SUCCESS; 1053a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi} 1054a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi 1055a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh SanghiTPM_RC TpmUtilityImpl::UnsealData(const std::string& sealed_data, 1056a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi AuthorizationDelegate* delegate, 1057a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi std::string* unsealed_data) { 1058a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi CHECK(unsealed_data); 1059a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi TPM_RC result; 1060a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi if (delegate == nullptr) { 1061a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi result = SAPI_RC_INVALID_SESSIONS; 1062b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 1063b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": This method needs a valid authorization delegate: " 1064a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi << GetErrorString(result); 1065a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi return result; 1066a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi } 1067a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi TPM_HANDLE object_handle; 106830c921db09d27768acc1ea0d8b6a9c8e814f931aLuis Hector Chavez std::unique_ptr<AuthorizationDelegate> password_delegate = 1069a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi factory_.GetPasswordAuthorization(""); 1070a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi result = LoadKey(sealed_data, password_delegate.get(), &object_handle); 1071a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 1072b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 1073b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Error loading sealed object: " << GetErrorString(result); 1074a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi return result; 1075a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi } 1076a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi ScopedKeyHandle sealed_object(factory_, object_handle); 1077a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi std::string object_name; 1078a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi result = GetKeyName(sealed_object.get(), &object_name); 1079a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 1080b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 1081b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Error getting object name: " << GetErrorString(result); 1082a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi return result; 1083a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi } 1084a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi TPM2B_SENSITIVE_DATA out_data; 1085a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi result = factory_.GetTpm()->UnsealSync(sealed_object.get(), object_name, 1086a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi &out_data, delegate); 1087a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 1088b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 1089b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Error unsealing object: " << GetErrorString(result); 1090a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi return result; 1091a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi } 1092a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi *unsealed_data = StringFrom_TPM2B_SENSITIVE_DATA(out_data); 1093a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi return TPM_RC_SUCCESS; 1094a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi} 1095a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi 1096a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh SanghiTPM_RC TpmUtilityImpl::StartSession(HmacSession* session) { 10974dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn TPM_RC result = session->StartUnboundSession(true /* enable_encryption */); 1098a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 1099b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Error starting unbound session: " 1100b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << GetErrorString(result); 1101a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi return result; 1102a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi } 1103a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi session->SetEntityAuthorizationValue(""); 1104a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi return TPM_RC_SUCCESS; 1105a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi} 1106a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi 1107a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh SanghiTPM_RC TpmUtilityImpl::GetPolicyDigestForPcrValue(int pcr_index, 1108a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi const std::string& pcr_value, 1109a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi std::string* policy_digest) { 1110a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi CHECK(policy_digest); 111130c921db09d27768acc1ea0d8b6a9c8e814f931aLuis Hector Chavez std::unique_ptr<PolicySession> session = factory_.GetTrialSession(); 1112a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi TPM_RC result = session->StartUnboundSession(false); 1113a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 1114b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Error starting unbound trial session: " 1115a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi << GetErrorString(result); 1116a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi return result; 1117a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi } 1118a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi std::string mutable_pcr_value; 1119a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi if (pcr_value.empty()) { 1120a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi result = ReadPCR(pcr_index, &mutable_pcr_value); 1121a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 1122b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 1123b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Error reading pcr_value: " << GetErrorString(result); 1124a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi return result; 1125a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi } 1126a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi } else { 1127a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi mutable_pcr_value = pcr_value; 1128a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi } 1129a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi result = session->PolicyPCR(pcr_index, mutable_pcr_value); 1130a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 1131b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Error restricting policy to PCR value: " 1132a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi << GetErrorString(result); 1133a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi return result; 1134a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi } 1135a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi result = session->GetDigest(policy_digest); 1136a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 1137b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 1138b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Error getting policy digest: " << GetErrorString(result); 1139a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi return result; 1140a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi } 1141a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi return TPM_RC_SUCCESS; 1142a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi} 1143a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi 114439dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh SanghiTPM_RC TpmUtilityImpl::DefineNVSpace(uint32_t index, 114539dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi size_t num_bytes, 1146b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn TPMA_NV attributes, 1147b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn const std::string& authorization_value, 1148b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn const std::string& policy_digest, 11495d3b9451ae2e912aefed0669dd50b2a777ea0ab2Utkarsh Sanghi AuthorizationDelegate* delegate) { 115039dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi TPM_RC result; 115139dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi if (num_bytes > MAX_NV_INDEX_SIZE) { 115239dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi result = SAPI_RC_BAD_SIZE; 1153b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 1154b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Cannot define non-volatile space of given size: " 115539dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi << GetErrorString(result); 115639dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi return result; 115739dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi } 115839dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi if (index > kMaxNVSpaceIndex) { 115939dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi result = SAPI_RC_BAD_PARAMETER; 1160b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 1161b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Cannot define non-volatile space with the given index: " 116239dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi << GetErrorString(result); 116339dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi return result; 116439dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi } 1165c04decde2a6e9b74395f402818852e752534254bUtkarsh Sanghi if (delegate == nullptr) { 116639dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi result = SAPI_RC_INVALID_SESSIONS; 1167b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 1168b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": This method needs a valid authorization delegate: " 116939dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi << GetErrorString(result); 117039dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi return result; 117139dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi } 117239dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi uint32_t nv_index = NV_INDEX_FIRST + index; 117339dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi TPMS_NV_PUBLIC public_data; 117439dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi public_data.nv_index = nv_index; 117539dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi public_data.name_alg = TPM_ALG_SHA256; 1176b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn public_data.attributes = attributes; 1177b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn public_data.auth_policy = Make_TPM2B_DIGEST(policy_digest); 117839dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi public_data.data_size = num_bytes; 1179b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn TPM2B_AUTH authorization = Make_TPM2B_DIGEST(authorization_value); 118039dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi TPM2B_NV_PUBLIC public_area = Make_TPM2B_NV_PUBLIC(public_data); 118139dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi result = factory_.GetTpm()->NV_DefineSpaceSync( 11824dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn TPM_RH_OWNER, NameFromHandle(TPM_RH_OWNER), authorization, public_area, 11835d3b9451ae2e912aefed0669dd50b2a777ea0ab2Utkarsh Sanghi delegate); 118439dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi if (result != TPM_RC_SUCCESS) { 1185b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Error defining non-volatile space: " 118639dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi << GetErrorString(result); 118739dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi return result; 118839dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi } 11896537cf15412f04bda9fc1a80f7209d55c955c61fUtkarsh Sanghi nvram_public_area_map_[index] = public_data; 119039dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi return TPM_RC_SUCCESS; 119139dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi} 119239dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi 119339dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh SanghiTPM_RC TpmUtilityImpl::DestroyNVSpace(uint32_t index, 11945d3b9451ae2e912aefed0669dd50b2a777ea0ab2Utkarsh Sanghi AuthorizationDelegate* delegate) { 119539dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi TPM_RC result; 119639dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi if (index > kMaxNVSpaceIndex) { 119739dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi result = SAPI_RC_BAD_PARAMETER; 1198b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 1199b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Cannot undefine non-volatile space with the given index: " 120039dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi << GetErrorString(result); 120139dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi return result; 120239dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi } 1203c04decde2a6e9b74395f402818852e752534254bUtkarsh Sanghi if (delegate == nullptr) { 120439dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi result = SAPI_RC_INVALID_SESSIONS; 1205b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 1206b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": This method needs a valid authorization delegate: " 120739dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi << GetErrorString(result); 120839dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi return result; 120939dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi } 121039dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi std::string nv_name; 121139dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi result = GetNVSpaceName(index, &nv_name); 121239dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi if (result != TPM_RC_SUCCESS) { 121339dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi return result; 121439dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi } 121539dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi uint32_t nv_index = NV_INDEX_FIRST + index; 121639dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi result = factory_.GetTpm()->NV_UndefineSpaceSync( 12174dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn TPM_RH_OWNER, NameFromHandle(TPM_RH_OWNER), nv_index, nv_name, delegate); 121839dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi if (result != TPM_RC_SUCCESS) { 1219b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Error undefining non-volatile space: " 122039dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi << GetErrorString(result); 122139dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi return result; 122239dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi } 12236537cf15412f04bda9fc1a80f7209d55c955c61fUtkarsh Sanghi nvram_public_area_map_.erase(index); 122439dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi return TPM_RC_SUCCESS; 122539dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi} 122639dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi 122739dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh SanghiTPM_RC TpmUtilityImpl::LockNVSpace(uint32_t index, 1228b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn bool lock_read, 1229b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn bool lock_write, 1230b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn bool using_owner_authorization, 12315d3b9451ae2e912aefed0669dd50b2a777ea0ab2Utkarsh Sanghi AuthorizationDelegate* delegate) { 123239dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi TPM_RC result; 123339dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi if (index > kMaxNVSpaceIndex) { 123439dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi result = SAPI_RC_BAD_PARAMETER; 1235b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 1236b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Cannot lock non-volatile space with the given index: " 123739dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi << GetErrorString(result); 123839dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi return result; 123939dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi } 124039dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi std::string nv_name; 124139dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi result = GetNVSpaceName(index, &nv_name); 124239dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi if (result != TPM_RC_SUCCESS) { 124339dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi return result; 124439dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi } 124539dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi uint32_t nv_index = NV_INDEX_FIRST + index; 1246b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn TPMI_RH_NV_AUTH auth_target = nv_index; 1247b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn std::string auth_target_name = nv_name; 1248b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn if (using_owner_authorization) { 1249b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn auth_target = TPM_RH_OWNER; 1250b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn auth_target_name = NameFromHandle(TPM_RH_OWNER); 125139dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi } 12526537cf15412f04bda9fc1a80f7209d55c955c61fUtkarsh Sanghi auto it = nvram_public_area_map_.find(index); 1253b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn if (lock_read) { 1254b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn result = factory_.GetTpm()->NV_ReadLockSync(auth_target, auth_target_name, 1255b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn nv_index, nv_name, delegate); 1256b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn if (result != TPM_RC_SUCCESS) { 1257b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Error locking non-volatile space read: " 1258b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << GetErrorString(result); 1259b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn return result; 1260b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn } 1261b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn if (it != nvram_public_area_map_.end()) { 1262b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn it->second.attributes |= TPMA_NV_READLOCKED; 1263b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn } 1264b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn } 1265b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn if (lock_write) { 1266b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn result = factory_.GetTpm()->NV_WriteLockSync(auth_target, auth_target_name, 1267b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn nv_index, nv_name, delegate); 1268b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn if (result != TPM_RC_SUCCESS) { 1269b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Error locking non-volatile space write: " 1270b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << GetErrorString(result); 1271b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn return result; 1272b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn } 1273b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn if (it != nvram_public_area_map_.end()) { 1274b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn it->second.attributes |= TPMA_NV_WRITELOCKED; 1275b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn } 12766537cf15412f04bda9fc1a80f7209d55c955c61fUtkarsh Sanghi } 127739dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi return TPM_RC_SUCCESS; 127839dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi} 127939dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi 128039dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh SanghiTPM_RC TpmUtilityImpl::WriteNVSpace(uint32_t index, 128139dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi uint32_t offset, 128239dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi const std::string& nvram_data, 1283b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn bool using_owner_authorization, 1284b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn bool extend, 12855d3b9451ae2e912aefed0669dd50b2a777ea0ab2Utkarsh Sanghi AuthorizationDelegate* delegate) { 128639dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi TPM_RC result; 128739dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi if (nvram_data.size() > MAX_NV_BUFFER_SIZE) { 128839dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi result = SAPI_RC_BAD_SIZE; 1289b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Insufficient buffer for non-volatile write: " 129039dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi << GetErrorString(result); 129139dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi return result; 129239dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi } 129339dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi if (index > kMaxNVSpaceIndex) { 129439dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi result = SAPI_RC_BAD_PARAMETER; 1295b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 1296b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Cannot write to non-volatile space with the given index: " 129739dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi << GetErrorString(result); 129839dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi return result; 129939dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi } 130039dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi std::string nv_name; 130139dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi result = GetNVSpaceName(index, &nv_name); 130239dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi if (result != TPM_RC_SUCCESS) { 130339dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi return result; 130439dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi } 130539dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi uint32_t nv_index = NV_INDEX_FIRST + index; 1306b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn TPMI_RH_NV_AUTH auth_target = nv_index; 1307b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn std::string auth_target_name = nv_name; 1308b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn if (using_owner_authorization) { 1309b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn auth_target = TPM_RH_OWNER; 1310b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn auth_target_name = NameFromHandle(TPM_RH_OWNER); 1311b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn } 1312b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn if (extend) { 1313b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn result = factory_.GetTpm()->NV_ExtendSync( 1314b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn auth_target, auth_target_name, nv_index, nv_name, 1315b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn Make_TPM2B_MAX_NV_BUFFER(nvram_data), delegate); 1316b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn } else { 1317b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn result = factory_.GetTpm()->NV_WriteSync( 1318b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn auth_target, auth_target_name, nv_index, nv_name, 1319b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn Make_TPM2B_MAX_NV_BUFFER(nvram_data), offset, delegate); 1320b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn } 132139dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi if (result != TPM_RC_SUCCESS) { 1322b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Error writing to non-volatile space: " 132339dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi << GetErrorString(result); 132439dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi return result; 132539dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi } 13266537cf15412f04bda9fc1a80f7209d55c955c61fUtkarsh Sanghi auto it = nvram_public_area_map_.find(index); 13276537cf15412f04bda9fc1a80f7209d55c955c61fUtkarsh Sanghi if (it != nvram_public_area_map_.end()) { 13286537cf15412f04bda9fc1a80f7209d55c955c61fUtkarsh Sanghi it->second.attributes |= TPMA_NV_WRITTEN; 13296537cf15412f04bda9fc1a80f7209d55c955c61fUtkarsh Sanghi } 133039dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi return TPM_RC_SUCCESS; 133139dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi} 133239dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi 133339dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh SanghiTPM_RC TpmUtilityImpl::ReadNVSpace(uint32_t index, 133439dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi uint32_t offset, 133539dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi size_t num_bytes, 1336b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn bool using_owner_authorization, 133739dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi std::string* nvram_data, 13385d3b9451ae2e912aefed0669dd50b2a777ea0ab2Utkarsh Sanghi AuthorizationDelegate* delegate) { 133939dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi TPM_RC result; 134039dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi if (num_bytes > MAX_NV_BUFFER_SIZE) { 134139dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi result = SAPI_RC_BAD_SIZE; 1342b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Insufficient buffer for non-volatile read: " 134339dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi << GetErrorString(result); 134439dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi return result; 134539dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi } 134639dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi if (index > kMaxNVSpaceIndex) { 134739dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi result = SAPI_RC_BAD_PARAMETER; 1348b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 1349b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Cannot read from non-volatile space with the given index: " 135039dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi << GetErrorString(result); 135139dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi return result; 135239dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi } 135339dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi std::string nv_name; 135439dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi result = GetNVSpaceName(index, &nv_name); 135539dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi if (result != TPM_RC_SUCCESS) { 135639dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi return result; 135739dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi } 135839dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi uint32_t nv_index = NV_INDEX_FIRST + index; 1359b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn TPMI_RH_NV_AUTH auth_target = nv_index; 1360b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn std::string auth_target_name = nv_name; 1361b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn if (using_owner_authorization) { 1362b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn auth_target = TPM_RH_OWNER; 1363b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn auth_target_name = NameFromHandle(TPM_RH_OWNER); 1364b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn } 136539dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi TPM2B_MAX_NV_BUFFER data_buffer; 136639dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi data_buffer.size = 0; 1367b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn result = factory_.GetTpm()->NV_ReadSync(auth_target, auth_target_name, 1368b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn nv_index, nv_name, num_bytes, offset, 1369b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn &data_buffer, delegate); 137039dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi if (result != TPM_RC_SUCCESS) { 1371b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Error reading from non-volatile space: " 137239dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi << GetErrorString(result); 137339dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi return result; 137439dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi } 137539dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi nvram_data->assign(StringFrom_TPM2B_MAX_NV_BUFFER(data_buffer)); 137639dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi return TPM_RC_SUCCESS; 137739dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi} 137839dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi 137939dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh SanghiTPM_RC TpmUtilityImpl::GetNVSpaceName(uint32_t index, std::string* name) { 138039dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi TPM_RC result; 138139dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi if (index > kMaxNVSpaceIndex) { 138239dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi result = SAPI_RC_BAD_PARAMETER; 1383b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 1384b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Cannot read from non-volatile space with the given index: " 138539dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi << GetErrorString(result); 138639dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi return result; 138739dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi } 138839dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi TPMS_NV_PUBLIC nv_public_data; 138939dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi result = GetNVSpacePublicArea(index, &nv_public_data); 139039dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi if (result != TPM_RC_SUCCESS) { 139139dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi return result; 139239dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi } 139339dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi result = ComputeNVSpaceName(nv_public_data, name); 139439dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi if (result != TPM_RC_SUCCESS) { 139539dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi return result; 139639dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi } 139739dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi return TPM_RC_SUCCESS; 139839dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi} 139939dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi 140039dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh SanghiTPM_RC TpmUtilityImpl::GetNVSpacePublicArea(uint32_t index, 140139dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi TPMS_NV_PUBLIC* public_data) { 140239dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi TPM_RC result; 140339dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi if (index > kMaxNVSpaceIndex) { 140439dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi result = SAPI_RC_BAD_PARAMETER; 1405b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 1406b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Cannot read from non-volatile space with the given index: " 140739dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi << GetErrorString(result); 140839dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi return result; 140939dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi } 14106537cf15412f04bda9fc1a80f7209d55c955c61fUtkarsh Sanghi auto it = nvram_public_area_map_.find(index); 14116537cf15412f04bda9fc1a80f7209d55c955c61fUtkarsh Sanghi if (it != nvram_public_area_map_.end()) { 14126537cf15412f04bda9fc1a80f7209d55c955c61fUtkarsh Sanghi *public_data = it->second; 14136537cf15412f04bda9fc1a80f7209d55c955c61fUtkarsh Sanghi return TPM_RC_SUCCESS; 14146537cf15412f04bda9fc1a80f7209d55c955c61fUtkarsh Sanghi } 141539dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi TPM2B_NAME nvram_name; 141639dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi TPM2B_NV_PUBLIC public_area; 141739dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi public_area.nv_public.nv_index = 0; 141839dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi uint32_t nv_index = NV_INDEX_FIRST + index; 14194dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn result = factory_.GetTpm()->NV_ReadPublicSync(nv_index, "", &public_area, 14204dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn &nvram_name, nullptr); 142139dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi if (result != TPM_RC_SUCCESS) { 1422b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 1423b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Error reading non-volatile space public information: " 142439dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi << GetErrorString(result); 142539dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi return result; 142639dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi } 142739dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi *public_data = public_area.nv_public; 14286537cf15412f04bda9fc1a80f7209d55c955c61fUtkarsh Sanghi nvram_public_area_map_[index] = public_area.nv_public; 142939dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi return TPM_RC_SUCCESS; 143039dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi} 143139dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi 1432b180754b429c078cbc99175a6059a8b5d0491002Darren KrahnTPM_RC TpmUtilityImpl::ListNVSpaces(std::vector<uint32_t>* index_list) { 1433b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn TPM_RC result; 1434b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn TPMI_YES_NO more_data = YES; 1435b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn TPMS_CAPABILITY_DATA capability_data; 1436b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn TPM_HANDLE handle_base = HR_NV_INDEX; 1437b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn while (more_data == YES) { 1438b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn result = factory_.GetTpm()->GetCapabilitySync( 1439b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn TPM_CAP_HANDLES, handle_base, MAX_CAP_HANDLES, &more_data, 1440b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn &capability_data, nullptr /*authorization_delegate*/); 1441b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn if (result != TPM_RC_SUCCESS) { 1442b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 1443b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Error querying NV spaces: " << GetErrorString(result); 1444b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn return result; 1445b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn } 1446b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn if (capability_data.capability != TPM_CAP_HANDLES) { 1447b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Invalid capability type."; 1448b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn return SAPI_RC_MALFORMED_RESPONSE; 1449b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn } 1450b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn TPML_HANDLE& handles = capability_data.data.handles; 1451b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn for (uint32_t i = 0; i < handles.count; ++i) { 1452b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn index_list->push_back(handles.handle[i] & HR_HANDLE_MASK); 1453b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn handle_base = handles.handle[i] + 1; 1454b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn } 1455b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn } 1456b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn return TPM_RC_SUCCESS; 1457b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn} 1458b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn 1459b180754b429c078cbc99175a6059a8b5d0491002Darren KrahnTPM_RC TpmUtilityImpl::SetDictionaryAttackParameters( 1460b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn uint32_t max_tries, 1461b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn uint32_t recovery_time, 1462b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn uint32_t lockout_recovery, 1463b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn AuthorizationDelegate* delegate) { 1464b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn return factory_.GetTpm()->DictionaryAttackParametersSync( 1465b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn TPM_RH_LOCKOUT, NameFromHandle(TPM_RH_LOCKOUT), max_tries, recovery_time, 1466b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn lockout_recovery, delegate); 1467b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn} 1468b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn 1469b180754b429c078cbc99175a6059a8b5d0491002Darren KrahnTPM_RC TpmUtilityImpl::ResetDictionaryAttackLock( 1470b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn AuthorizationDelegate* delegate) { 1471b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn return factory_.GetTpm()->DictionaryAttackLockResetSync( 1472b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn TPM_RH_LOCKOUT, NameFromHandle(TPM_RH_LOCKOUT), delegate); 1473b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn} 1474b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn 147566d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh SanghiTPM_RC TpmUtilityImpl::SetKnownOwnerPassword( 147666d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi const std::string& known_owner_password) { 147730c921db09d27768acc1ea0d8b6a9c8e814f931aLuis Hector Chavez std::unique_ptr<TpmState> tpm_state(factory_.GetTpmState()); 147866d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi TPM_RC result = tpm_state->Initialize(); 147966d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi if (result) { 148066d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi LOG(ERROR) << __func__ << ": " << GetErrorString(result); 148166d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi return result; 148266d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi } 148330c921db09d27768acc1ea0d8b6a9c8e814f931aLuis Hector Chavez std::unique_ptr<AuthorizationDelegate> delegate = 148466d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi factory_.GetPasswordAuthorization(""); 148566d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi if (tpm_state->IsOwnerPasswordSet()) { 1486b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(INFO) << __func__ << ": Owner password is already set. " 148766d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi << "This is normal if ownership is already taken."; 148866d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi return TPM_RC_SUCCESS; 148966d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi } 14904dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn result = SetHierarchyAuthorization(TPM_RH_OWNER, known_owner_password, 149166d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi delegate.get()); 149266d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi if (result) { 1493b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Error setting storage hierarchy authorization " 149466d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi << "to its default value: " << GetErrorString(result); 149566d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi return result; 149666d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi } 149766d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi return TPM_RC_SUCCESS; 149866d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi} 149966d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi 150066d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh SanghiTPM_RC TpmUtilityImpl::CreateStorageRootKeys( 150166d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi const std::string& owner_password) { 150266d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi TPM_RC result = TPM_RC_SUCCESS; 150330c921db09d27768acc1ea0d8b6a9c8e814f931aLuis Hector Chavez std::unique_ptr<TpmState> tpm_state(factory_.GetTpmState()); 150466d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi result = tpm_state->Initialize(); 150566d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi if (result) { 150666d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi LOG(ERROR) << __func__ << ": " << GetErrorString(result); 150766d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi return result; 150866d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi } 150966d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi Tpm* tpm = factory_.GetTpm(); 151066d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi TPML_PCR_SELECTION creation_pcrs; 151166d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi creation_pcrs.count = 0; 151266d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi TPMS_SENSITIVE_CREATE sensitive; 151366d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi sensitive.user_auth = Make_TPM2B_DIGEST(""); 151466d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi sensitive.data = Make_TPM2B_SENSITIVE_DATA(""); 151566d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi TPM_HANDLE object_handle; 151666d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi TPM2B_CREATION_DATA creation_data; 151766d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi TPM2B_DIGEST creation_digest; 151866d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi TPMT_TK_CREATION creation_ticket; 151966d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi TPM2B_NAME object_name; 152066d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi object_name.size = 0; 152130c921db09d27768acc1ea0d8b6a9c8e814f931aLuis Hector Chavez std::unique_ptr<AuthorizationDelegate> delegate = 152266d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi factory_.GetPasswordAuthorization(owner_password); 152387b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn if (tpm_state->IsRSASupported()) { 152487b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn bool exists = false; 152587b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn result = DoesPersistentKeyExist(kRSAStorageRootKey, &exists); 152666d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi if (result) { 152766d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi return result; 152866d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi } 152987b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn if (!exists) { 153087b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn TPMT_PUBLIC public_area = CreateDefaultPublicArea(TPM_ALG_RSA); 15314dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn public_area.object_attributes |= (kSensitiveDataOrigin | kUserWithAuth | 15324dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn kNoDA | kRestricted | kDecrypt); 153387b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn public_area.parameters.rsa_detail.symmetric.algorithm = TPM_ALG_AES; 153487b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn public_area.parameters.rsa_detail.symmetric.key_bits.aes = 128; 153587b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn public_area.parameters.rsa_detail.symmetric.mode.aes = TPM_ALG_CFB; 153687b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn TPM2B_PUBLIC rsa_public_area = Make_TPM2B_PUBLIC(public_area); 15374dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn result = tpm->CreatePrimarySync( 15384dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn TPM_RH_OWNER, NameFromHandle(TPM_RH_OWNER), 15394dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn Make_TPM2B_SENSITIVE_CREATE(sensitive), rsa_public_area, 15404dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn Make_TPM2B_DATA(""), creation_pcrs, &object_handle, &rsa_public_area, 15414dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn &creation_data, &creation_digest, &creation_ticket, &object_name, 15424dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn delegate.get()); 154387b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn if (result) { 154487b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn LOG(ERROR) << __func__ << ": " << GetErrorString(result); 154587b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn return result; 154687b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn } 154787b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn ScopedKeyHandle rsa_key(factory_, object_handle); 154887b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn // This will make the key persistent. 15494dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn result = tpm->EvictControlSync(TPM_RH_OWNER, NameFromHandle(TPM_RH_OWNER), 155087b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn object_handle, 155187b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn StringFrom_TPM2B_NAME(object_name), 15524dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn kRSAStorageRootKey, delegate.get()); 155387b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn if (result != TPM_RC_SUCCESS) { 155487b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn LOG(ERROR) << __func__ << ": " << GetErrorString(result); 155587b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn return result; 155687b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn } 1557b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(INFO) << __func__ << ": Created RSA SRK."; 155887b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn } else { 1559b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(INFO) << __func__ << ": Skip RSA SRK because it already exists."; 156066d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi } 156166d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi } else { 1562b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(INFO) << __func__ << ": Skip RSA SRK because RSA is not supported."; 156366d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi } 156466d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi 156566d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi // Do it again for ECC. 156687b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn if (tpm_state->IsRSASupported()) { 156787b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn bool exists = false; 156887b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn result = DoesPersistentKeyExist(kECCStorageRootKey, &exists); 156966d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi if (result) { 157066d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi return result; 157166d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi } 157287b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn if (!exists) { 157387b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn TPMT_PUBLIC public_area = CreateDefaultPublicArea(TPM_ALG_ECC); 15744dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn public_area.object_attributes |= (kSensitiveDataOrigin | kUserWithAuth | 15754dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn kNoDA | kRestricted | kDecrypt); 157687b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn public_area.parameters.ecc_detail.symmetric.algorithm = TPM_ALG_AES; 157787b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn public_area.parameters.ecc_detail.symmetric.key_bits.aes = 128; 157887b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn public_area.parameters.ecc_detail.symmetric.mode.aes = TPM_ALG_CFB; 157987b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn TPM2B_PUBLIC ecc_public_area = Make_TPM2B_PUBLIC(public_area); 15804dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn result = tpm->CreatePrimarySync( 15814dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn TPM_RH_OWNER, NameFromHandle(TPM_RH_OWNER), 15824dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn Make_TPM2B_SENSITIVE_CREATE(sensitive), ecc_public_area, 15834dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn Make_TPM2B_DATA(""), creation_pcrs, &object_handle, &ecc_public_area, 15844dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn &creation_data, &creation_digest, &creation_ticket, &object_name, 15854dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn delegate.get()); 158687b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn if (result) { 158787b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn LOG(ERROR) << __func__ << ": " << GetErrorString(result); 158887b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn return result; 158987b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn } 159087b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn ScopedKeyHandle ecc_key(factory_, object_handle); 159187b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn // This will make the key persistent. 15924dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn result = tpm->EvictControlSync(TPM_RH_OWNER, NameFromHandle(TPM_RH_OWNER), 159387b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn object_handle, 159487b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn StringFrom_TPM2B_NAME(object_name), 15954dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn kECCStorageRootKey, delegate.get()); 159687b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn if (result != TPM_RC_SUCCESS) { 159787b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn LOG(ERROR) << __func__ << ": " << GetErrorString(result); 159887b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn return result; 159987b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn } 1600b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(INFO) << __func__ << ": Created ECC SRK."; 160187b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn } else { 1602b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(INFO) << __func__ << ": Skip ECC SRK because it already exists."; 160366d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi } 160466d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi } else { 1605b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(INFO) << __func__ << ": Skip ECC SRK because ECC is not supported."; 160666d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi } 160766d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi return TPM_RC_SUCCESS; 160866d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi} 160966d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi 161066d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh SanghiTPM_RC TpmUtilityImpl::CreateSaltingKey(const std::string& owner_password) { 161187b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn bool exists = false; 161287b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn TPM_RC result = DoesPersistentKeyExist(kSaltingKey, &exists); 161387b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn if (result != TPM_RC_SUCCESS) { 161466d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi return result; 161566d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi } 161687b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn if (exists) { 1617b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(INFO) << __func__ << ": Salting key already exists."; 161887b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn return TPM_RC_SUCCESS; 161987b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn } 162066d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi std::string parent_name; 162166d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi result = GetKeyName(kRSAStorageRootKey, &parent_name); 162266d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi if (result != TPM_RC_SUCCESS) { 1623b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Error getting Key name for RSA-SRK: " 162466d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi << GetErrorString(result); 162566d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi return result; 162666d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi } 162787b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn TPMT_PUBLIC public_area = CreateDefaultPublicArea(TPM_ALG_RSA); 162812a12083abb8fc9b1bd9ac69e2be983bb7227818Jocelyn Bohr public_area.name_alg = TPM_ALG_SHA256; 162966d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi public_area.object_attributes |= 163066d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi kSensitiveDataOrigin | kUserWithAuth | kNoDA | kDecrypt; 163166d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi TPML_PCR_SELECTION creation_pcrs; 163266d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi creation_pcrs.count = 0; 163366d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi TPMS_SENSITIVE_CREATE sensitive; 163466d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi sensitive.user_auth = Make_TPM2B_DIGEST(""); 163566d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi sensitive.data = Make_TPM2B_SENSITIVE_DATA(""); 16364dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn TPM2B_SENSITIVE_CREATE sensitive_create = 16374dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn Make_TPM2B_SENSITIVE_CREATE(sensitive); 163866d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi TPM2B_DATA outside_info = Make_TPM2B_DATA(""); 163966d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi 164066d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi TPM2B_PRIVATE out_private; 164166d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi out_private.size = 0; 164266d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi TPM2B_PUBLIC out_public; 164366d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi out_public.size = 0; 164466d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi TPM2B_CREATION_DATA creation_data; 164566d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi TPM2B_DIGEST creation_hash; 164666d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi TPMT_TK_CREATION creation_ticket; 164766d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi // TODO(usanghi): MITM vulnerability with SaltingKey creation. 164866d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi // Currently we cannot verify the key returned by the TPM. 164966d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi // crbug.com/442331 165030c921db09d27768acc1ea0d8b6a9c8e814f931aLuis Hector Chavez std::unique_ptr<AuthorizationDelegate> delegate = 165166d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi factory_.GetPasswordAuthorization(""); 16524dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn result = factory_.GetTpm()->CreateSync( 16534dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn kRSAStorageRootKey, parent_name, sensitive_create, 16544dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn Make_TPM2B_PUBLIC(public_area), outside_info, creation_pcrs, &out_private, 16554dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn &out_public, &creation_data, &creation_hash, &creation_ticket, 16564dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn delegate.get()); 165766d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi if (result != TPM_RC_SUCCESS) { 1658b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 1659b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Error creating salting key: " << GetErrorString(result); 166066d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi return result; 166166d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi } 166266d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi TPM2B_NAME key_name; 166366d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi key_name.size = 0; 166466d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi TPM_HANDLE key_handle; 16654dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn result = factory_.GetTpm()->LoadSync(kRSAStorageRootKey, parent_name, 16664dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn out_private, out_public, &key_handle, 16674dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn &key_name, delegate.get()); 166866d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi if (result != TPM_RC_SUCCESS) { 1669b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 1670b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Error loading salting key: " << GetErrorString(result); 167166d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi return result; 167266d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi } 167366d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi ScopedKeyHandle key(factory_, key_handle); 167430c921db09d27768acc1ea0d8b6a9c8e814f931aLuis Hector Chavez std::unique_ptr<AuthorizationDelegate> owner_delegate = 167566d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi factory_.GetPasswordAuthorization(owner_password); 16764dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn result = factory_.GetTpm()->EvictControlSync( 16774dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn TPM_RH_OWNER, NameFromHandle(TPM_RH_OWNER), key_handle, 16784dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn StringFrom_TPM2B_NAME(key_name), kSaltingKey, owner_delegate.get()); 167966d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi if (result != TPM_RC_SUCCESS) { 168066d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi LOG(ERROR) << __func__ << ": " << GetErrorString(result); 168166d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi return result; 168266d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi } 168366d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi return TPM_RC_SUCCESS; 168466d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi} 168566d0d268e571647ca99a2bdf4835d967449d7ddeUtkarsh Sanghi 16866465502c740d2599d95e09232c744f6d2ed54505Utkarsh SanghiTPMT_PUBLIC TpmUtilityImpl::CreateDefaultPublicArea(TPM_ALG_ID key_alg) { 16876465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi TPMT_PUBLIC public_area; 16886465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi public_area.name_alg = TPM_ALG_SHA256; 16896465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi public_area.auth_policy = Make_TPM2B_DIGEST(""); 16906465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi public_area.object_attributes = kFixedTPM | kFixedParent; 16916465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi if (key_alg == TPM_ALG_RSA) { 16926465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi public_area.type = TPM_ALG_RSA; 16936465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi public_area.parameters.rsa_detail.scheme.scheme = TPM_ALG_NULL; 16946465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi public_area.parameters.rsa_detail.symmetric.algorithm = TPM_ALG_NULL; 16956465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi public_area.parameters.rsa_detail.key_bits = 2048; 16966465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi public_area.parameters.rsa_detail.exponent = 0; 16976465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi public_area.unique.rsa = Make_TPM2B_PUBLIC_KEY_RSA(""); 16986465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi } else if (key_alg == TPM_ALG_ECC) { 16996465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi public_area.type = TPM_ALG_ECC; 17006465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi public_area.parameters.ecc_detail.curve_id = TPM_ECC_NIST_P256; 1701f5b84250f024416a2bf47b088ea79a22cba1240eUtkarsh Sanghi public_area.parameters.ecc_detail.kdf.scheme = TPM_ALG_NULL; 17026465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi public_area.unique.ecc.x = Make_TPM2B_ECC_PARAMETER(""); 17036465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi public_area.unique.ecc.y = Make_TPM2B_ECC_PARAMETER(""); 1704a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi } else if (key_alg == TPM_ALG_KEYEDHASH) { 1705a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi public_area.type = TPM_ALG_KEYEDHASH; 1706a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi public_area.parameters.keyed_hash_detail.scheme.scheme = TPM_ALG_NULL; 17076465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi } else { 1708b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(WARNING) << __func__ 1709b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Unrecognized key_type. Not filling parameters."; 17106465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi } 17116465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi return public_area; 17126465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi} 17136465502c740d2599d95e09232c744f6d2ed54505Utkarsh Sanghi 171452e2a45f585fbe34032eae5b094a092afdf217caDarren KrahnTPM_RC TpmUtilityImpl::SetHierarchyAuthorization( 171552e2a45f585fbe34032eae5b094a092afdf217caDarren Krahn TPMI_RH_HIERARCHY_AUTH hierarchy, 171652e2a45f585fbe34032eae5b094a092afdf217caDarren Krahn const std::string& password, 171752e2a45f585fbe34032eae5b094a092afdf217caDarren Krahn AuthorizationDelegate* authorization) { 1718e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi if (password.size() > kMaxPasswordLength) { 1719b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Hierarchy passwords can be at most " 1720b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << kMaxPasswordLength 1721e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi << " bytes. Current password length is: " << password.size(); 1722e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi return SAPI_RC_BAD_SIZE; 1723e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi } 172452e2a45f585fbe34032eae5b094a092afdf217caDarren Krahn return factory_.GetTpm()->HierarchyChangeAuthSync( 17254dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn hierarchy, NameFromHandle(hierarchy), Make_TPM2B_DIGEST(password), 172652e2a45f585fbe34032eae5b094a092afdf217caDarren Krahn authorization); 1727c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn} 1728c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn 1729c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren KrahnTPM_RC TpmUtilityImpl::DisablePlatformHierarchy( 1730c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn AuthorizationDelegate* authorization) { 1731c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn return factory_.GetTpm()->HierarchyControlSync( 1732c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn TPM_RH_PLATFORM, // The authorizing entity. 1733c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn NameFromHandle(TPM_RH_PLATFORM), 1734c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn TPM_RH_PLATFORM, // The target hierarchy. 17354dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn 0, // Disable. 1736c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn authorization); 1737c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn} 1738c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn 173933ca033c9665b8496f3491037403ae1574a54227Utkarsh SanghiTPM_RC TpmUtilityImpl::ComputeKeyName(const TPMT_PUBLIC& public_area, 174033ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi std::string* object_name) { 17418b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi CHECK(object_name); 17428b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi if (public_area.type == TPM_ALG_ERROR) { 17438b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi // We do not compute a name for empty public area. 17448b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi object_name->clear(); 17458b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi return TPM_RC_SUCCESS; 17468b2bf63478b292937f85b3b0e215882af461a999Utkarsh Sanghi } 174733ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi std::string serialized_public_area; 174833ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi TPM_RC result = Serialize_TPMT_PUBLIC(public_area, &serialized_public_area); 174933ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 1750b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 1751b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Error serializing public area: " << GetErrorString(result); 175233ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi return result; 175380c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn } 175433ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi std::string serialized_name_alg; 175533ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi result = Serialize_TPM_ALG_ID(TPM_ALG_SHA256, &serialized_name_alg); 175633ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 1757b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 1758b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Error serializing public area: " << GetErrorString(result); 175933ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi return result; 176080c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn } 176133ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi object_name->assign(serialized_name_alg + 176233ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi crypto::SHA256HashString(serialized_public_area)); 176333ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi return TPM_RC_SUCCESS; 176433ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi} 176533ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi 176639dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh SanghiTPM_RC TpmUtilityImpl::ComputeNVSpaceName(const TPMS_NV_PUBLIC& nv_public_area, 176739dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi std::string* nv_name) { 176839dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi CHECK(nv_name); 176939dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi if ((nv_public_area.nv_index & NV_INDEX_FIRST) == 0) { 177039dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi // If the index is not an nvram index, we do not compute a name. 177139dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi nv_name->clear(); 177239dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi return TPM_RC_SUCCESS; 177339dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi } 177439dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi std::string serialized_public_area; 17754dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn TPM_RC result = 17764dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn Serialize_TPMS_NV_PUBLIC(nv_public_area, &serialized_public_area); 177739dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi if (result != TPM_RC_SUCCESS) { 1778b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 1779b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Error serializing public area: " << GetErrorString(result); 178039dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi return result; 178139dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi } 178239dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi std::string serialized_name_alg; 178339dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi result = Serialize_TPM_ALG_ID(TPM_ALG_SHA256, &serialized_name_alg); 178439dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi if (result != TPM_RC_SUCCESS) { 1785b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 1786b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Error serializing public area: " << GetErrorString(result); 178739dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi return result; 178839dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi } 178939dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi nv_name->assign(serialized_name_alg + 179039dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi crypto::SHA256HashString(serialized_public_area)); 179139dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi return TPM_RC_SUCCESS; 179239dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi} 179339dd58452d7fe3ebe93490a6239a76b385bd676dUtkarsh Sanghi 179433ca033c9665b8496f3491037403ae1574a54227Utkarsh SanghiTPM_RC TpmUtilityImpl::EncryptPrivateData(const TPMT_SENSITIVE& sensitive_area, 179533ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi const TPMT_PUBLIC& public_area, 179633ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi TPM2B_PRIVATE* encrypted_private_data, 179733ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi TPM2B_DATA* encryption_key) { 179833ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi TPM2B_SENSITIVE sensitive_data = Make_TPM2B_SENSITIVE(sensitive_area); 179933ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi std::string serialized_sensitive_data; 18004dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn TPM_RC result = 18014dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn Serialize_TPM2B_SENSITIVE(sensitive_data, &serialized_sensitive_data); 180233ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 1803b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Error serializing sensitive data: " 180433ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi << GetErrorString(result); 180533ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi return result; 180680c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn } 180733ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi std::string object_name; 180833ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi result = ComputeKeyName(public_area, &object_name); 180933ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 1810b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 1811b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Error computing object name: " << GetErrorString(result); 181233ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi return result; 181380c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn } 18144dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn TPM2B_DIGEST inner_integrity = Make_TPM2B_DIGEST( 18154dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn crypto::SHA256HashString(serialized_sensitive_data + object_name)); 181633ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi std::string serialized_inner_integrity; 181733ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi result = Serialize_TPM2B_DIGEST(inner_integrity, &serialized_inner_integrity); 181833ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 1819b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ << ": Error serializing inner integrity: " 182033ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi << GetErrorString(result); 182133ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi return result; 182280c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn } 18234dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn std::string unencrypted_private_data = 18244dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn serialized_inner_integrity + serialized_sensitive_data; 182533ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi AES_KEY key; 182633ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi AES_set_encrypt_key(encryption_key->buffer, kAesKeySize * 8, &key); 182733ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi std::string private_data_string(unencrypted_private_data.size(), 0); 182833ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi int iv_in = 0; 182933ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi unsigned char iv[MAX_AES_BLOCK_SIZE_BYTES] = {0}; 183033ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi AES_cfb128_encrypt( 18314dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn reinterpret_cast<const unsigned char*>(unencrypted_private_data.data()), 18324dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn reinterpret_cast<unsigned char*>(string_as_array(&private_data_string)), 18334dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn unencrypted_private_data.size(), &key, iv, &iv_in, AES_ENCRYPT); 183433ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi *encrypted_private_data = Make_TPM2B_PRIVATE(private_data_string); 183533ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 1836b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn LOG(ERROR) << __func__ 1837b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn << ": Error making private area: " << GetErrorString(result); 183833ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi return result; 183980c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn } 184033ca033c9665b8496f3491037403ae1574a54227Utkarsh Sanghi return TPM_RC_SUCCESS; 184180c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn} 184280c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn 184387b642d428ca28ff81b97ab0617f2c04d8605683Darren KrahnTPM_RC TpmUtilityImpl::DoesPersistentKeyExist(TPMI_DH_PERSISTENT key_handle, 184487b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn bool* exists) { 184587b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn TPM_RC result; 184687b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn TPMI_YES_NO more_data = YES; 184787b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn TPMS_CAPABILITY_DATA capability_data; 184887b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn result = factory_.GetTpm()->GetCapabilitySync( 184987b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn TPM_CAP_HANDLES, key_handle, 1 /*property_count*/, &more_data, 185087b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn &capability_data, nullptr /*authorization_delegate*/); 185187b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn if (result != TPM_RC_SUCCESS) { 185287b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn LOG(ERROR) << __func__ 185387b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn << ": Error querying handles: " << GetErrorString(result); 185487b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn return result; 185587b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn } 185687b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn TPML_HANDLE& handles = capability_data.data.handles; 185787b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn *exists = (handles.count == 1 && handles.handle[0] == key_handle); 185887b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn return TPM_RC_SUCCESS; 185987b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn} 186087b642d428ca28ff81b97ab0617f2c04d8605683Darren Krahn 1861c364caa9d091baae8eeb9144a6abf69e1fcabb39Darren Krahn} // namespace trunks 1862