1bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// 2bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// Copyright (C) 2015 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// 164ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 174ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn#include "trunks/resource_manager.h" 184ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 194ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn#include <algorithm> 204ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn#include <map> 214ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn#include <set> 224ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn#include <string> 234ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn#include <vector> 244ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 254ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn#include <base/callback.h> 264ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 274ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn#include "trunks/error_codes.h" 284ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 294ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnnamespace { 304ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 314ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnconst int kMaxCommandAttempts = 3; 324ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnconst size_t kMinimumAuthorizationSize = 9; 334ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnconst size_t kMessageHeaderSize = 10; 344ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnconst trunks::TPM_HANDLE kMaxVirtualHandle = 354ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn (trunks::HR_TRANSIENT + trunks::HR_HANDLE_MASK); 364ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 374ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnclass ScopedBool { 384ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn public: 394ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn ScopedBool() : target_(nullptr) {} 404ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn ~ScopedBool() { 414ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (target_) { 424ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn *target_ = false; 434ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 444ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 454ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn void Enable(bool* target) { 464ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn target_ = target; 474ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn *target_ = true; 484ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 494ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn private: 504ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn bool* target_; 514ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn}; 524ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 534ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn} // namespace 544ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 554ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnnamespace trunks { 564ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 574ede7fcc1571b23867536b2506900fc3987c2dd5Darren KrahnResourceManager::ResourceManager(const TrunksFactory& factory, 584ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn CommandTransceiver* next_transceiver) 594ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn : factory_(factory), 604ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn next_transceiver_(next_transceiver) {} 614ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 624ede7fcc1571b23867536b2506900fc3987c2dd5Darren KrahnResourceManager::~ResourceManager() {} 634ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 644ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnvoid ResourceManager::Initialize() { 654ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn TPM_RC result = factory_.GetTpm()->StartupSync(TPM_SU_CLEAR, nullptr); 664ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // Ignore TPM_RC_INITIALIZE, that means it was already started. 679caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn CHECK(result == TPM_RC_SUCCESS || result == TPM_RC_INITIALIZE) 689caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn << "TPM startup failure: " << GetErrorString(result); 694ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn result = factory_.GetTpm()->SelfTestSync(YES /* Full test. */, nullptr); 709caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn CHECK_EQ(result, TPM_RC_SUCCESS) << "TPM self-test failure: " 719caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn << GetErrorString(result); 724ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // Full control of the TPM is assumed and required. Existing transient object 734ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // and session handles are mercilessly flushed. 744ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn for (UINT32 handle_type : {HR_TRANSIENT, 754ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn HR_HMAC_SESSION, 764ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn HR_POLICY_SESSION}) { 774ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn TPMI_YES_NO more_data = YES; 784ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn TPMS_CAPABILITY_DATA data; 794ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn UINT32 handle_range = handle_type; 804ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn while (more_data) { 814ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn result = factory_.GetTpm()->GetCapabilitySync(TPM_CAP_HANDLES, 824ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn handle_range, 834ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn MAX_CAP_HANDLES, 844ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn &more_data, 854ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn &data, 864ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn nullptr); 874ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (result != TPM_RC_SUCCESS) { 884ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn LOG(WARNING) << "Failed to query existing handles: " 894ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn << GetErrorString(result); 904ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn break; 914ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 924ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn const TPML_HANDLE& handle_list = data.data.handles; 934ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn for (UINT32 i = 0; i < handle_list.count; ++i) { 944ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn factory_.GetTpm()->FlushContextSync(handle_list.handle[i], nullptr); 954ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 964ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (more_data) { 974ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // Adjust the range to be greater than the most recent handle so on the 984ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // next query we'll start where we left off. 994ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn handle_range = handle_list.handle[handle_list.count-1]; 1004ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 1014ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 1024ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 1034ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn} 1044ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 1054ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnvoid ResourceManager::SendCommand( 1064ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn const std::string& command, 1074ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn const ResponseCallback& callback) { 1084ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn callback.Run(SendCommandAndWait(command)); 1094ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn} 1104ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 1114ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnstd::string ResourceManager::SendCommandAndWait(const std::string& command) { 1124ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // Sanitize the |command|. If this succeeds consistency of the command header 1134ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // and the size of all other sections can be assumed. 1144ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn MessageInfo command_info; 1154ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn TPM_RC result = ParseCommand(command, &command_info); 1164ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (result != TPM_RC_SUCCESS) { 1174ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return CreateErrorResponse(result); 1184ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 1194ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // A special case for FlushContext. It requires special handling because it 1204ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // has a handle as a parameter and because we need to cleanup if it succeeds. 1214ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (command_info.code == TPM_CC_FlushContext) { 1224ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return ProcessFlushContext(command, command_info); 1234ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 1244ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // Process all the input handles, e.g. map virtual handles. 1254ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::vector<TPM_HANDLE> updated_handles; 1264ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn for (auto handle : command_info.handles) { 1274ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn TPM_HANDLE tpm_handle; 1284ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn result = ProcessInputHandle(command_info, handle, &tpm_handle); 1294ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (result != TPM_RC_SUCCESS) { 1304ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return CreateErrorResponse(result); 1314ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 1324ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn updated_handles.push_back(tpm_handle); 1334ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 1344ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::string updated_command = ReplaceHandles(command, updated_handles); 1354ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // Make sure all the required sessions are loaded. 1364ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn for (auto handle : command_info.session_handles) { 1374ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn result = EnsureSessionIsLoaded(command_info, handle); 1384ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (result != TPM_RC_SUCCESS) { 1394ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return CreateErrorResponse(result); 1404ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 1414ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 1424ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // On a ContextLoad we may need to map virtualized context data. 1434ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (command_info.code == TPM_CC_ContextLoad) { 1444ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::string actual_load_data = GetActualContextFromExternalContext( 1454ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn command_info.parameter_data); 1464ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // Check equality to see if replacement is necessary, and check size to see 1474ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // if the command looks like we expect (the idea is to avoid 'fixing' 1484ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // malformed commands). Note: updated_command.size() is guaranteed to be >= 1494ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // kMessageHeaderSize based on the sanitization in ParseCommand. 1504ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (actual_load_data != command_info.parameter_data && 1514ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn actual_load_data.size() == 1524ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn updated_command.size() - kMessageHeaderSize) { 1534ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // Replace the parameter section of the command with |actual_load_data|. 1544ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn VLOG(1) << "REPLACE_EXTERNAL_CONTEXT"; 1554ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn updated_command.replace(kMessageHeaderSize, std::string::npos, 1564ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn actual_load_data); 1574ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 1584ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 1594ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // Send the |updated_command| to the next layer. Attempt to fix any actionable 1604ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // warnings for up to kMaxCommandAttempts. 1614ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::string response; 1624ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn MessageInfo response_info; 1634ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn int attempts = 0; 1644ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn while (attempts++ < kMaxCommandAttempts) { 1654ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn response = next_transceiver_->SendCommandAndWait(updated_command); 1664ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn result = ParseResponse(command_info, response, &response_info); 1674ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (result != TPM_RC_SUCCESS) { 1684ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return CreateErrorResponse(result); 1694ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 1704ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (!FixWarnings(command_info, response_info.code)) { 1714ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // No actionable warnings were handled. 1724ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn break; 1734ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 1744ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 1754ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (response_info.code == TPM_RC_SUCCESS) { 1764ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (response_info.session_continued.size() != 1774ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn command_info.session_handles.size()) { 1784ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn LOG(WARNING) << "Session count mismatch!"; 1794ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 1804ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // Cleanup any sessions that were not continued. 1814ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn for (size_t i = 0; i < command_info.session_handles.size(); ++i) { 1824ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (i < response_info.session_continued.size() && 1834ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn !response_info.session_continued[i]) { 1844ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn CleanupFlushedHandle(command_info.session_handles[i]); 1854ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 1864ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 1874ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // On a successful context save we need to cache the context data in case it 1884ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // needs to be virtualized later. 1894ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (command_info.code == TPM_CC_ContextSave) { 1904ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn ProcessExternalContextSave(command_info, response_info); 1914ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 1924ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // Process all the output handles, which is loosely the inverse of the input 1934ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // handle processing. E.g. virtualize handles. 1944ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::vector<TPM_HANDLE> virtual_handles; 1954ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn for (auto handle : response_info.handles) { 1964ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn virtual_handles.push_back(ProcessOutputHandle(handle)); 1974ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 1984ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn response = ReplaceHandles(response, virtual_handles); 1994ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 2004ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return response; 2014ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn} 2024ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 2034ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnbool ResourceManager::ChooseSessionToEvict( 2044ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn const std::vector<TPM_HANDLE>& sessions_to_retain, 2054ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn TPM_HANDLE* session_to_evict) { 2064ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // Build a list of candidates by excluding |sessions_to_retain|. 2074ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::vector<TPM_HANDLE> candidates; 2084ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn for (auto& item : session_handles_) { 2094ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn HandleInfo& info = item.second; 2104ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (info.is_loaded && 2114ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::find(sessions_to_retain.begin(), 2124ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn sessions_to_retain.end(), 2134ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn info.tpm_handle) == sessions_to_retain.end()) { 2144ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn candidates.push_back(item.first); 2154ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 2164ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 2174ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (candidates.empty()) { 2184ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn LOG(WARNING) << "No sessions to evict."; 2194ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return false; 2204ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 2214ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // Choose the candidate with the earliest |time_of_last_use|. 2224ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn auto oldest_iter = std::min_element( 2234ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn candidates.begin(), candidates.end(), 2244ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn [this](TPM_HANDLE a, TPM_HANDLE b) { 2254ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return (session_handles_[a].time_of_last_use < 2264ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn session_handles_[b].time_of_last_use); 2274ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn }); 2284ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn *session_to_evict = *oldest_iter; 2294ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return true; 2304ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn} 2314ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 2324ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnvoid ResourceManager::CleanupFlushedHandle(TPM_HANDLE flushed_handle) { 2334ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (IsObjectHandle(flushed_handle)) { 2344ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // For transient object handles, remove both the actual and virtual handles. 2354ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (virtual_object_handles_.count(flushed_handle) > 0) { 2364ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn tpm_object_handles_.erase( 2374ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn virtual_object_handles_[flushed_handle].tpm_handle); 2384ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn virtual_object_handles_.erase(flushed_handle); 2394ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 2404ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } else if (IsSessionHandle(flushed_handle)) { 2414ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn auto iter = session_handles_.find(flushed_handle); 2424ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (iter == session_handles_.end()) { 2434ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return; 2444ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 2454ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // For session handles, remove the handle and any associated context data. 2464ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn HandleInfo& info = iter->second; 2474ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (!info.is_loaded) { 2484ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::string actual_context_data; 2494ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn Serialize_TPMS_CONTEXT(info.context, &actual_context_data); 2504ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (actual_context_to_external_.count(actual_context_data) > 0) { 2514ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn external_context_to_actual_.erase( 2524ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn actual_context_to_external_[actual_context_data]); 2534ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn actual_context_to_external_.erase(actual_context_data); 2544ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 2554ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 2564ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn session_handles_.erase(flushed_handle); 2574ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn VLOG(1) << "CLEANUP_SESSION: " << std::hex << flushed_handle; 2584ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 2594ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn} 2604ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 2614ede7fcc1571b23867536b2506900fc3987c2dd5Darren KrahnTPM_HANDLE ResourceManager::CreateVirtualHandle() { 2624ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn TPM_HANDLE handle; 2634ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn do { 2644ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn handle = next_virtual_handle_; 2654ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (next_virtual_handle_ == kMaxVirtualHandle) { 2664ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn next_virtual_handle_ = TRANSIENT_FIRST; 2674ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } else { 2684ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn ++next_virtual_handle_; 2694ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 2704ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } while (virtual_object_handles_.count(handle) > 0); 2714ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return handle; 2724ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn} 2734ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 2744ede7fcc1571b23867536b2506900fc3987c2dd5Darren KrahnTPM_RC ResourceManager::EnsureSessionIsLoaded(const MessageInfo& command_info, 2754ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn TPM_HANDLE session_handle) { 2764ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // A password authorization can skip all this. 2774ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (session_handle == TPM_RS_PW) { 2784ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return TPM_RC_SUCCESS; 2794ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 2804ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn auto handle_iter = session_handles_.find(session_handle); 2814ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (handle_iter == session_handles_.end()) { 2824ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return MakeError(TPM_RC_HANDLE, FROM_HERE); 2834ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 2844ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn HandleInfo& handle_info = handle_iter->second; 2854ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (!handle_info.is_loaded) { 2864ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn TPM_RC result = LoadContext(command_info, &handle_info); 2874ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (result != TPM_RC_SUCCESS) { 2884ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return result; 2894ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 2904ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn VLOG(1) << "RELOAD_SESSION: " << std::hex << session_handle; 2914ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 2924ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn handle_info.time_of_last_use = base::TimeTicks::Now(); 2934ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return TPM_RC_SUCCESS; 2944ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn} 2954ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 2964ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnvoid ResourceManager::EvictObjects(const MessageInfo& command_info) { 2974ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn for (auto& item : virtual_object_handles_) { 2984ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn HandleInfo& info = item.second; 2994ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (!info.is_loaded || 3004ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::find(command_info.handles.begin(), 3014ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn command_info.handles.end(), 3024ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn item.first) != command_info.handles.end()) { 3034ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn continue; 3044ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 3054ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn TPM_RC result = SaveContext(command_info, &info); 3064ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (result != TPM_RC_SUCCESS) { 3074ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn LOG(WARNING) << "Failed to save transient object: " 3084ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn << GetErrorString(result); 3094ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn continue; 3104ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 3114ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn result = factory_.GetTpm()->FlushContextSync(info.tpm_handle, nullptr); 3124ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (result != TPM_RC_SUCCESS) { 3134ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn LOG(WARNING) << "Failed to evict transient object: " 3144ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn << GetErrorString(result); 3154ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn continue; 3164ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 3174ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn tpm_object_handles_.erase(info.tpm_handle); 3184ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn VLOG(1) << "EVICT_OBJECT: " << std::hex << info.tpm_handle; 3194ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 3204ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn} 3214ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 3224ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnvoid ResourceManager::EvictSession(const MessageInfo& command_info) { 3234ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn TPM_HANDLE session_to_evict; 3244ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (!ChooseSessionToEvict(command_info.session_handles, &session_to_evict)) { 3254ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return; 3264ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 3274ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn HandleInfo& info = session_handles_[session_to_evict]; 3284ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn TPM_RC result = SaveContext(command_info, &info); 3294ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (result != TPM_RC_SUCCESS) { 3304ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn LOG(WARNING) << "Failed to evict session: " << GetErrorString(result); 3314ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 3324ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn VLOG(1) << "EVICT_SESSION: " << std::hex << session_to_evict; 3334ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn} 3344ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 3354ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnstd::vector<TPM_HANDLE> ResourceManager::ExtractHandlesFromBuffer( 3364ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn size_t number_of_handles, 3374ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::string* buffer) { 3384ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::vector<TPM_HANDLE> handles(number_of_handles); 3394ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn for (size_t i = 0; i < number_of_handles; ++i) { 3404ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn TPM_HANDLE handle; 3414ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (TPM_RC_SUCCESS == Parse_TPM_HANDLE(buffer, &handle, nullptr)) { 3424ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn handles[i] = handle; 3434ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 3444ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 3454ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return handles; 3464ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn} 3474ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 3484ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnvoid ResourceManager::FixContextGap(const MessageInfo& command_info) { 3494ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::vector<TPM_HANDLE> sessions_to_ungap; 3504ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn for (const auto& item : session_handles_) { 3514ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn const HandleInfo& info = item.second; 3524ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (!info.is_loaded) { 3534ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn sessions_to_ungap.push_back(item.first); 3544ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 3554ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 3564ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // Sort by |time_of_create|. 3574ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::sort(sessions_to_ungap.begin(), sessions_to_ungap.end(), 3584ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn [this](TPM_HANDLE a, TPM_HANDLE b) { 3594ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return (session_handles_[a].time_of_create < 3604ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn session_handles_[b].time_of_create); 3614ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn }); 3624ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn for (auto handle : sessions_to_ungap) { 3634ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn HandleInfo& info = session_handles_[handle]; 3644ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // Loading and re-saving allows the TPM to assign a new context counter. 3654ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::string old_context_blob; 3664ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn Serialize_TPMS_CONTEXT(info.context, &old_context_blob); 3674ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn TPM_RC result = LoadContext(command_info, &info); 3684ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (result != TPM_RC_SUCCESS) { 3694ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn LOG(WARNING) << "Failed to un-gap session (load): " 3704ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn << GetErrorString(result); 3714ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn continue; 3724ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 3734ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn result = SaveContext(command_info, &info); 3744ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (result != TPM_RC_SUCCESS) { 3754ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn LOG(WARNING) << "Failed to un-gap session (save): " 3764ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn << GetErrorString(result); 3774ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn continue; 3784ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 3794ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // If this context is one that we're tracking for external use, update it. 3804ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn auto iter = actual_context_to_external_.find(old_context_blob); 3814ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (iter == actual_context_to_external_.end()) { 3824ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn continue; 3834ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 3844ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::string new_context_blob; 3854ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn Serialize_TPMS_CONTEXT(info.context, &new_context_blob); 3864ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn const std::string& external_context_blob = iter->second; 3874ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn actual_context_to_external_[new_context_blob] = external_context_blob; 3884ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn external_context_to_actual_[external_context_blob] = new_context_blob; 3894ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn actual_context_to_external_.erase(old_context_blob); 3904ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 3914ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn} 3924ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 3934ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnbool ResourceManager::FixWarnings(const MessageInfo& command_info, 3944ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn TPM_RC result) { 3954ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if ((result & RC_WARN) == 0) { 3964ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return false; 3974ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 3984ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // This method can be called anytime without tracking whether the current 3994ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // operation is already an attempt to fix a warning. All re-entrance issues 4004ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // are dealt with here using the following rule: Never attempt to fix the same 4014ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // warning twice. 4024ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn ScopedBool scoped_bool; 4034ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (!fixing_warnings_) { 4044ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn scoped_bool.Enable(&fixing_warnings_); 4054ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn warnings_already_seen_.clear(); 4064ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } else if (warnings_already_seen_.count(result) > 0) { 4074ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return false; 4084ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 4094ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn warnings_already_seen_.insert(result); 4104ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn switch (result) { 4114ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn case TPM_RC_CONTEXT_GAP: 4124ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn FixContextGap(command_info); 4134ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return true; 4144ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn case TPM_RC_OBJECT_MEMORY: 4154ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn case TPM_RC_OBJECT_HANDLES: 4164ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn EvictObjects(command_info); 4174ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return true; 4184ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn case TPM_RC_SESSION_MEMORY: 4194ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn EvictSession(command_info); 4204ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return true; 4214ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn case TPM_RC_MEMORY: 4224ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn EvictObjects(command_info); 4234ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn EvictSession(command_info); 4244ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return true; 4254ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn case TPM_RC_SESSION_HANDLES: 4264ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn FlushSession(command_info); 4274ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return true; 4284ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 4294ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return false; 4304ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn} 4314ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 4324ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnvoid ResourceManager::FlushSession(const MessageInfo& command_info) { 4334ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn TPM_HANDLE session_to_flush; 4344ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn LOG(WARNING) << "Resource manager needs to flush a session."; 4354ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (!ChooseSessionToEvict(command_info.session_handles, &session_to_flush)) { 4364ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return; 4374ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 4384ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn TPM_RC result = factory_.GetTpm()->FlushContextSync(session_to_flush, 4394ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn nullptr); 4404ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (result != TPM_RC_SUCCESS) { 4414ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn LOG(WARNING) << "Failed to flush session: " << GetErrorString(result); 4424ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return; 4434ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 4444ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn CleanupFlushedHandle(session_to_flush); 4454ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn} 4464ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 4474ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnstd::string ResourceManager::GetActualContextFromExternalContext( 4484ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn const std::string& external_context) { 4494ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn auto iter = external_context_to_actual_.find(external_context); 4504ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (iter == external_context_to_actual_.end()) { 4514ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return external_context; 4524ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 4534ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return iter->second; 4544ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn} 4554ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 4564ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnbool ResourceManager::IsObjectHandle(TPM_HANDLE handle) const { 4574ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return ((handle & HR_RANGE_MASK) == HR_TRANSIENT); 4584ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn} 4594ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 4604ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnbool ResourceManager::IsSessionHandle(TPM_HANDLE handle) const { 4614ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return ((handle & HR_RANGE_MASK) == HR_HMAC_SESSION || 4624ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn (handle & HR_RANGE_MASK) == HR_POLICY_SESSION); 4634ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn} 4644ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 4654ede7fcc1571b23867536b2506900fc3987c2dd5Darren KrahnTPM_RC ResourceManager::LoadContext(const MessageInfo& command_info, 4664ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn HandleInfo* handle_info) { 4674ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn CHECK(!handle_info->is_loaded); 4684ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn TPM_RC result = TPM_RC_SUCCESS; 4694ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn int attempts = 0; 4704ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn while (attempts++ < kMaxCommandAttempts) { 4714ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn result = factory_.GetTpm()->ContextLoadSync(handle_info->context, 4724ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn &handle_info->tpm_handle, 4734ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn nullptr); 4744ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (!FixWarnings(command_info, result)) { 4754ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn break; 4764ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 4774ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 4784ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (result != TPM_RC_SUCCESS) { 4794ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn LOG(ERROR) << __func__ << ": Failed to load context: " 4804ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn << GetErrorString(result); 4814ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return result; 4824ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 4834ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn handle_info->is_loaded = true; 4844ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return result; 4854ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn} 4864ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 4874ede7fcc1571b23867536b2506900fc3987c2dd5Darren KrahnTPM_RC ResourceManager::MakeError(TPM_RC tpm_error, 4884ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn const ::tracked_objects::Location& location) { 4894ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn LOG(ERROR) << "ResourceManager::" << location.function_name() << ":" 4904ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn << location.line_number() << ": " << GetErrorString(tpm_error); 4914ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return tpm_error + kResourceManagerTpmErrorBase; 4924ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn} 4934ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 4944ede7fcc1571b23867536b2506900fc3987c2dd5Darren KrahnTPM_RC ResourceManager::ParseCommand(const std::string& command, 4954ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn MessageInfo* command_info) { 4964ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn CHECK(command_info); 4974ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::string buffer = command; 4984ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn TPM_ST tag; 4994ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn TPM_RC result = Parse_TPM_ST(&buffer, &tag, nullptr); 5004ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (result != TPM_RC_SUCCESS) { 5014ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return MakeError(result, FROM_HERE); 5024ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 5034ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (tag != TPM_ST_SESSIONS && tag != TPM_ST_NO_SESSIONS) { 5044ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return MakeError(TPM_RC_TAG, FROM_HERE); 5054ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 5064ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn command_info->has_sessions = (tag == TPM_ST_SESSIONS); 5074ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 5084ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn UINT32 size = 0; 5094ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn result = Parse_UINT32(&buffer, &size, nullptr); 5104ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (result != TPM_RC_SUCCESS) { 5114ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return MakeError(result, FROM_HERE); 5124ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 5134ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (size != command.size()) { 5144ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return MakeError(TPM_RC_SIZE, FROM_HERE); 5154ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 5164ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 5174ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn result = Parse_TPM_CC(&buffer, &command_info->code, nullptr); 5184ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (result != TPM_RC_SUCCESS) { 5194ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return MakeError(result, FROM_HERE); 5204ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 5214ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (command_info->code < TPM_CC_FIRST || command_info->code > TPM_CC_LAST) { 5224ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return MakeError(TPM_RC_COMMAND_CODE, FROM_HERE); 5234ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 5244ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 5254ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn size_t number_of_handles = GetNumberOfRequestHandles(command_info->code); 5264ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn command_info->handles = ExtractHandlesFromBuffer(number_of_handles, &buffer); 5274ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (number_of_handles != command_info->handles.size()) { 5284ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return MakeError(TPM_RC_SIZE, FROM_HERE); 5294ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 5304ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (command_info->has_sessions) { 5314ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // Sessions exist, so we're expecting a valid authorization size value. 5324ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn UINT32 authorization_size = 0; 5334ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn result = Parse_UINT32(&buffer, &authorization_size, nullptr); 5344ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (result != TPM_RC_SUCCESS) { 5354ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return MakeError(result, FROM_HERE); 5364ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 5374ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (buffer.size() < authorization_size || 5384ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn authorization_size < kMinimumAuthorizationSize) { 5394ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return MakeError(TPM_RC_SIZE, FROM_HERE); 5404ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 5414ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // Move out the parameter bytes, leaving only the authorization section. 5424ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn command_info->parameter_data = buffer.substr(authorization_size); 5434ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn buffer.erase(authorization_size); 5444ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // Parse as many authorization sessions as there are in the section. 5454ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn while (!buffer.empty()) { 5464ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn TPM_HANDLE handle; 5474ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn result = Parse_TPM_HANDLE(&buffer, &handle, nullptr); 5484ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (result != TPM_RC_SUCCESS) { 5494ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return MakeError(result, FROM_HERE); 5504ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 5514ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (handle != TPM_RS_PW && session_handles_.count(handle) == 0) { 5524ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return MakeError(TPM_RC_HANDLE, FROM_HERE); 5534ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 5544ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn TPM2B_NONCE nonce; 5554ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn result = Parse_TPM2B_NONCE(&buffer, &nonce, nullptr); 5564ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (result != TPM_RC_SUCCESS) { 5574ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return MakeError(result, FROM_HERE); 5584ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 5594ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn BYTE attributes; 5604ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn result = Parse_BYTE(&buffer, &attributes, nullptr); 5614ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (result != TPM_RC_SUCCESS) { 5624ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return MakeError(result, FROM_HERE); 5634ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 5644ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn TPM2B_DIGEST authorization; 5654ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn result = Parse_TPM2B_DIGEST(&buffer, &authorization, nullptr); 5664ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (result != TPM_RC_SUCCESS) { 5674ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return MakeError(result, FROM_HERE); 5684ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 5694ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn command_info->session_handles.push_back(handle); 5704ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn command_info->session_continued.push_back((attributes & 1) == 1); 5714ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 5724ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } else { 5734ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // No sessions, so all remaining data is parameter data. 5744ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn command_info->parameter_data = buffer; 5754ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 5764ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return TPM_RC_SUCCESS; 5774ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn} 5784ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 5794ede7fcc1571b23867536b2506900fc3987c2dd5Darren KrahnTPM_RC ResourceManager::ParseResponse(const MessageInfo& command_info, 5804ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn const std::string& response, 5814ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn MessageInfo* response_info) { 5824ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn CHECK(response_info); 5834ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::string buffer = response; 5844ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn TPM_ST tag; 5854ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn TPM_RC result = Parse_TPM_ST(&buffer, &tag, nullptr); 5864ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (result != TPM_RC_SUCCESS) { 5874ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return MakeError(result, FROM_HERE); 5884ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 5894ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (tag != TPM_ST_SESSIONS && tag != TPM_ST_NO_SESSIONS) { 5904ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return MakeError(TPM_RC_TAG, FROM_HERE); 5914ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 5924ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn response_info->has_sessions = (tag == TPM_ST_SESSIONS); 5934ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 5944ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn UINT32 size = 0; 5954ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn result = Parse_UINT32(&buffer, &size, nullptr); 5964ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (result != TPM_RC_SUCCESS) { 5974ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return MakeError(result, FROM_HERE); 5984ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 5994ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (size != response.size()) { 6004ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return MakeError(TPM_RC_SIZE, FROM_HERE); 6014ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 6024ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 6034ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn result = Parse_TPM_RC(&buffer, &response_info->code, nullptr); 6044ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (result != TPM_RC_SUCCESS) { 6054ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return MakeError(result, FROM_HERE); 6064ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 6074ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 6084ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn size_t number_of_handles = GetNumberOfResponseHandles(command_info.code); 6094ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn response_info->handles = ExtractHandlesFromBuffer(number_of_handles, &buffer); 6104ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (number_of_handles != response_info->handles.size()) { 6114ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return MakeError(TPM_RC_SIZE, FROM_HERE); 6124ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 6134ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (response_info->has_sessions) { 6144ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // Sessions exist, so we're expecting a valid parameter size value. 6154ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn UINT32 parameter_size = 0; 6164ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn result = Parse_UINT32(&buffer, ¶meter_size, nullptr); 6174ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (result != TPM_RC_SUCCESS) { 6184ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return MakeError(result, FROM_HERE); 6194ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 6204ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (buffer.size() < parameter_size) { 6214ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return MakeError(TPM_RC_SIZE, FROM_HERE); 6224ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 6234ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // Move out the parameter bytes, leaving only the authorization section. 6244ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn response_info->parameter_data = buffer.substr(0, parameter_size); 6254ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn buffer.erase(0, parameter_size); 6264ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // Parse as many authorization sessions as there are in the section. 6274ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn while (!buffer.empty()) { 6284ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn TPM2B_NONCE nonce; 6294ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn result = Parse_TPM2B_NONCE(&buffer, &nonce, nullptr); 6304ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (result != TPM_RC_SUCCESS) { 6314ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return MakeError(result, FROM_HERE); 6324ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 6334ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn BYTE attributes; 6344ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn result = Parse_BYTE(&buffer, &attributes, nullptr); 6354ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (result != TPM_RC_SUCCESS) { 6364ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return MakeError(result, FROM_HERE); 6374ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 6384ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn TPM2B_DIGEST acknowledgement; 6394ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn result = Parse_TPM2B_DIGEST(&buffer, &acknowledgement, nullptr); 6404ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (result != TPM_RC_SUCCESS) { 6414ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return MakeError(result, FROM_HERE); 6424ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 6434ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn response_info->session_continued.push_back((attributes & 1) == 1); 6444ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 6454ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } else { 6464ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // No sessions, so all remaining data is parameter data. 6474ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn response_info->parameter_data = buffer; 6484ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 6494ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return TPM_RC_SUCCESS; 6504ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn} 6514ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 6524ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnvoid ResourceManager::ProcessExternalContextSave( 6534ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn const MessageInfo& command_info, 6544ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn const MessageInfo& response_info) { 6554ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn CHECK_EQ(command_info.code, TPM_CC_ContextSave); 6564ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (command_info.handles.size() != 1) { 6574ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn LOG(WARNING) << "Invalid context save command."; 6584ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return; 6594ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 6604ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // We know command_info.handles[0] is valid because this is validated when the 6614ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // command is parsed. 6624ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn TPM_HANDLE saved_handle = command_info.handles[0]; 6634ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // Only track external context data for session handles. 6644ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (!IsSessionHandle(saved_handle)) { 6654ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return; 6664ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 6674ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::string mutable_parameter = response_info.parameter_data; 6684ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn TPMS_CONTEXT context; 6694ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::string context_blob; 6704ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn TPM_RC result = Parse_TPMS_CONTEXT(&mutable_parameter, 6714ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn &context, 6724ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn &context_blob); 6734ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (result != TPM_RC_SUCCESS) { 6744ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn LOG(WARNING) << "Invalid context save response: " << GetErrorString(result); 6754ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return; 6764ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 6774ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn auto iter = session_handles_.find(saved_handle); 6784ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (iter != session_handles_.end()) { 6794ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn iter->second.is_loaded = false; 6804ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn iter->second.context = context; 6814ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } else { 6824ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // Unknown handle? Not anymore. 6834ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn LOG(WARNING) << "Context for unknown handle."; 6844ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn HandleInfo new_handle_info; 6854ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn new_handle_info.Init(saved_handle); 6864ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn new_handle_info.is_loaded = false; 6874ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn new_handle_info.context = context; 6884ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn session_handles_[saved_handle] = new_handle_info; 6894ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 6904ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // Use the original context data as the 'external' context data. If this gets 6914ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // virtualized, only the 'actual' context data will change. 6924ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn external_context_to_actual_[context_blob] = context_blob; 6934ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn actual_context_to_external_[context_blob] = context_blob; 6944ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn} 6954ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 6964ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnstd::string ResourceManager::ProcessFlushContext( 6974ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn const std::string& command, 6984ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn const MessageInfo& command_info) { 6994ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::string buffer = command_info.parameter_data; 7004ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // There must be exactly one handle in the parameters section. 7014ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::vector<TPM_HANDLE> handles = ExtractHandlesFromBuffer(1, &buffer); 7024ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (handles.size() != 1) { 7034ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return CreateErrorResponse(MakeError(TPM_RC_SIZE, FROM_HERE)); 7044ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 7054ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn TPM_HANDLE handle = handles[0]; 7064ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn TPM_HANDLE actual_handle = handle; 7074ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (IsObjectHandle(handle)) { 7084ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn auto iter = virtual_object_handles_.find(handle); 7094ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (iter == virtual_object_handles_.end()) { 7104ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return CreateErrorResponse(MakeError(TPM_RC_HANDLE, FROM_HERE)); 7114ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 7124ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (!iter->second.is_loaded) { 7134ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // The handle wasn't loaded so no need to bother the TPM. 7144ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn CleanupFlushedHandle(handle); 7154ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return CreateErrorResponse(TPM_RC_SUCCESS); 7164ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 7174ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn actual_handle = iter->second.tpm_handle; 7184ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 7194ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // Send a command with the original header but with |actual_handle| as the 7204ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // parameter. 7214ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::string handle_blob; 7224ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn Serialize_TPM_HANDLE(actual_handle, &handle_blob); 7234ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::string updated_command = command.substr(0, kMessageHeaderSize) + 7244ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn handle_blob; 7254ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // No need to loop and fix warnings, there are no actionable warnings on when 7264ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // flushing context. 7274ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::string response = next_transceiver_->SendCommandAndWait(updated_command); 7284ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn MessageInfo response_info; 7294ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn TPM_RC result = ParseResponse(command_info, response, &response_info); 7304ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (result != TPM_RC_SUCCESS) { 7314ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return CreateErrorResponse(result); 7324ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 7334ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // Cleanup the handle locally even if the TPM did not recognize it. 7344ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (response_info.code == TPM_RC_SUCCESS || 7354ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn response_info.code == TPM_RC_HANDLE) { 7364ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn CleanupFlushedHandle(handle); 7374ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 7384ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return response; 7394ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn} 7404ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 7414ede7fcc1571b23867536b2506900fc3987c2dd5Darren KrahnTPM_RC ResourceManager::ProcessInputHandle(const MessageInfo& command_info, 7424ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn TPM_HANDLE virtual_handle, 7434ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn TPM_HANDLE* actual_handle) { 7444ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // Only transient object handles are virtualized. 7454ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (!IsObjectHandle(virtual_handle)) { 7464ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn *actual_handle = virtual_handle; 7474ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return TPM_RC_SUCCESS; 7484ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 7494ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn auto handle_iter = virtual_object_handles_.find(virtual_handle); 7504ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (handle_iter == virtual_object_handles_.end()) { 7514ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return MakeError(TPM_RC_HANDLE, FROM_HERE); 7524ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 7534ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn HandleInfo& handle_info = handle_iter->second; 7544ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (!handle_info.is_loaded) { 7554ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn TPM_RC result = LoadContext(command_info, &handle_info); 7564ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (result != TPM_RC_SUCCESS) { 7574ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return result; 7584ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 7594ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn tpm_object_handles_[handle_info.tpm_handle] = virtual_handle; 7604ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn VLOG(1) << "RELOAD_OBJECT: " << std::hex << virtual_handle; 7614ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 7624ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn VLOG(1) << "INPUT_HANDLE_REPLACE: " << std::hex << virtual_handle << " -> " 7634ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn << std::hex << handle_info.tpm_handle; 7644ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn *actual_handle = handle_info.tpm_handle; 7654ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return TPM_RC_SUCCESS; 7664ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn} 7674ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 7684ede7fcc1571b23867536b2506900fc3987c2dd5Darren KrahnTPM_HANDLE ResourceManager::ProcessOutputHandle(TPM_HANDLE handle) { 7694ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // Track, but do not virtualize, session handles. 7704ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (IsSessionHandle(handle)) { 7714ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn auto session_handle_iter = session_handles_.find(handle); 7724ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (session_handle_iter == session_handles_.end()) { 7734ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn HandleInfo new_handle_info; 7744ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn new_handle_info.Init(handle); 7754ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn session_handles_[handle] = new_handle_info; 7764ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn VLOG(1) << "OUTPUT_HANDLE_NEW_SESSION: " << std::hex << handle; 7774ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 7784ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return handle; 7794ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 7804ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn // Only transient object handles are virtualized. 7814ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (!IsObjectHandle(handle)) { 7824ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return handle; 7834ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 7844ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn auto virtual_handle_iter = tpm_object_handles_.find(handle); 7854ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (virtual_handle_iter == tpm_object_handles_.end()) { 7864ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn TPM_HANDLE new_virtual_handle = CreateVirtualHandle(); 7874ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn HandleInfo new_handle_info; 7884ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn new_handle_info.Init(handle); 7894ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn virtual_object_handles_[new_virtual_handle] = new_handle_info; 7904ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn tpm_object_handles_[handle] = new_virtual_handle; 7914ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn VLOG(1) << "OUTPUT_HANDLE_NEW_VIRTUAL: " << std::hex << handle << " -> " 7924ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn << std::hex << new_virtual_handle; 7934ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return new_virtual_handle; 7944ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 7954ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn VLOG(1) << "OUTPUT_HANDLE_REPLACE: " << std::hex << handle << " -> " 7964ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn << std::hex << virtual_handle_iter->second; 7974ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return virtual_handle_iter->second; 7984ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn} 7994ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 8004ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnstd::string ResourceManager::ReplaceHandles( 8014ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn const std::string& message, 8024ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn const std::vector<TPM_HANDLE>& new_handles) { 8034ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::string handles_blob; 8044ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn for (auto handle : new_handles) { 8054ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn CHECK_EQ(Serialize_TPM_HANDLE(handle, &handles_blob), TPM_RC_SUCCESS); 8064ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 8074ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::string mutable_message = message; 8084ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn CHECK_GE(message.size(), kMessageHeaderSize + handles_blob.size()); 8094ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return mutable_message.replace(kMessageHeaderSize, handles_blob.size(), 8104ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn handles_blob); 8114ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn} 8124ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 8134ede7fcc1571b23867536b2506900fc3987c2dd5Darren KrahnTPM_RC ResourceManager::SaveContext(const MessageInfo& command_info, 8144ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn HandleInfo* handle_info) { 8154ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn CHECK(handle_info->is_loaded); 8164ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn TPM_RC result = TPM_RC_SUCCESS; 8174ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn int attempts = 0; 8184ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn while (attempts++ < kMaxCommandAttempts) { 8194ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::string tpm_handle_name; 8204ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn Serialize_TPM_HANDLE(handle_info->tpm_handle, &tpm_handle_name); 8214ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn result = factory_.GetTpm()->ContextSaveSync(handle_info->tpm_handle, 8224ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn tpm_handle_name, 8234ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn &handle_info->context, 8244ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn nullptr); 8254ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (!FixWarnings(command_info, result)) { 8264ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn break; 8274ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 8284ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 8294ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (result != TPM_RC_SUCCESS) { 8304ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn LOG(ERROR) << __func__ << ": Failed to load context: " 8314ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn << GetErrorString(result); 8324ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return result; 8334ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 8344ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn handle_info->is_loaded = false; 8354ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return result; 8364ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn} 8374ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 8384ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 8394ede7fcc1571b23867536b2506900fc3987c2dd5Darren KrahnResourceManager::HandleInfo::HandleInfo() 8404ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn : is_loaded(false), 8414ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn tpm_handle(0) { 8424ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn memset(&context, 0, sizeof(TPMS_CONTEXT)); 8434ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn} 8444ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 8454ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnvoid ResourceManager::HandleInfo::Init(TPM_HANDLE handle) { 8464ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn tpm_handle = handle; 8474ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn is_loaded = true; 8484ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn time_of_create = base::TimeTicks::Now(); 8494ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn time_of_last_use = base::TimeTicks::Now(); 8504ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn} 8514ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 8524ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn} // namespace trunks 853