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 <string>
204ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn#include <vector>
214ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
224ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn#include <base/bind.h>
234ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn#include <gmock/gmock.h>
244ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn#include <gtest/gtest.h>
254ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
264ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn#include "trunks/error_codes.h"
274ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn#include "trunks/mock_command_transceiver.h"
284ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn#include "trunks/mock_tpm.h"
294ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn#include "trunks/trunks_factory_for_test.h"
304ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
314ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnusing testing::_;
324ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnusing testing::DoAll;
334ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnusing testing::Eq;
344ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnusing testing::Field;
354ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnusing testing::InSequence;
364ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnusing testing::Return;
374ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnusing testing::ReturnPointee;
384ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnusing testing::SetArgumentPointee;
394ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnusing testing::StrictMock;
404ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
414ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnnamespace {
424ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
434ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnconst trunks::TPM_HANDLE kArbitraryObjectHandle = trunks::TRANSIENT_FIRST + 25;
444ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnconst trunks::TPM_HANDLE kArbitrarySessionHandle = trunks::HMAC_SESSION_FIRST;
454ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
464ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnvoid Assign(std::string* to, const std::string& from) {
474ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  *to = from;
484ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn}
494ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
504ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnclass ScopedDisableLogging {
514ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn public:
524ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  ScopedDisableLogging() : original_severity_(logging::GetMinLogLevel()) {
534ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    logging::SetMinLogLevel(logging::LOG_FATAL);
544ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
554ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  ~ScopedDisableLogging() {
564ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    logging::SetMinLogLevel(original_severity_);
574ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
584ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
594ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn private:
604ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  logging::LogSeverity original_severity_;
614ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn};
624ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
634ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn}  // namespace
644ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
654ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnnamespace trunks {
664ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
674ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnclass ResourceManagerTest : public testing::Test {
684ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn public:
694ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  const std::vector<TPM_HANDLE> kNoHandles;
704ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  const std::string kNoAuthorization;
714ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  const std::string kNoParameters;
724ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
734ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  ResourceManagerTest() : resource_manager_(factory_, &transceiver_) {}
744ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  ~ResourceManagerTest() override {}
754ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
764ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  void SetUp() override {
774ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    factory_.set_tpm(&tpm_);
784ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
794ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
804ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  // Builds a well-formed command.
814ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string CreateCommand(TPM_CC code,
824ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                            const std::vector<TPM_HANDLE>& handles,
834ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                            const std::string& authorization,
844ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                            const std::string& parameters) {
854ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    std::string buffer;
864ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    TPM_ST tag = authorization.empty() ? TPM_ST_NO_SESSIONS : TPM_ST_SESSIONS;
874ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    UINT32 size = 10 + (handles.size() * 4) + authorization.size() +
884ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                  parameters.size() + (authorization.empty() ? 0 : 4);
894ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    Serialize_TPM_ST(tag, &buffer);
904ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    Serialize_UINT32(size, &buffer);
914ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    Serialize_TPM_CC(code, &buffer);
924ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    for (auto handle : handles) {
934ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      Serialize_TPM_HANDLE(handle, &buffer);
944ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    }
954ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    if (!authorization.empty()) {
964ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      Serialize_UINT32(authorization.size(), &buffer);
974ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    }
984ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    return buffer + authorization + parameters;
994ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
1004ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
1014ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  // Builds a well-formed response.
1024ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string CreateResponse(TPM_RC code,
1034ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                             const std::vector<TPM_HANDLE>& handles,
1044ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                             const std::string& authorization,
1054ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                             const std::string& parameters) {
1064ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    std::string buffer;
1074ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    TPM_ST tag = authorization.empty() ? TPM_ST_NO_SESSIONS : TPM_ST_SESSIONS;
1084ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    UINT32 size = 10 + (handles.size() * 4) + authorization.size() +
1094ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                  parameters.size() + (authorization.empty() ? 0 : 4);
1104ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    Serialize_TPM_ST(tag, &buffer);
1114ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    Serialize_UINT32(size, &buffer);
1124ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    Serialize_TPM_RC(code, &buffer);
1134ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    for (auto handle : handles) {
1144ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      Serialize_TPM_HANDLE(handle, &buffer);
1154ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    }
1164ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    if (!authorization.empty()) {
1174ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      Serialize_UINT32(parameters.size(), &buffer);
1184ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    }
1194ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    return buffer + parameters + authorization;
1204ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
1214ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
1224ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  // Builds a well-formed command authorization section.
1234ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string CreateCommandAuthorization(TPM_HANDLE handle,
1244ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                         bool continue_session) {
1254ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    std::string buffer;
1264ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    Serialize_TPM_HANDLE(handle, &buffer);
1274ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    Serialize_TPM2B_NONCE(Make_TPM2B_DIGEST(std::string(32, 'A')), &buffer);
1284ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    Serialize_BYTE(continue_session ? 1 : 0, &buffer);
1294ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    Serialize_TPM2B_DIGEST(Make_TPM2B_DIGEST(std::string(32, 'B')), &buffer);
1304ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    return buffer;
1314ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
1324ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
1334ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  // Builds a well-formed response authorization section.
1344ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string CreateResponseAuthorization(bool continue_session) {
1354ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    std::string buffer;
1364ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    Serialize_TPM2B_NONCE(Make_TPM2B_DIGEST(std::string(32, 'A')), &buffer);
1374ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    Serialize_BYTE(continue_session ? 1 : 0, &buffer);
1384ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    Serialize_TPM2B_DIGEST(Make_TPM2B_DIGEST(std::string(32, 'B')), &buffer);
1394ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    return buffer;
1404ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
1414ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
1424ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string GetHeader(const std::string& message) {
1434ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    return message.substr(0, 10);
1444ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
1454ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
1464ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string StripHeader(const std::string& message) {
1474ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    return message.substr(10);
1484ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
1494ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
1504ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  // Makes the resource manager aware of a transient object handle and returns
1514ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  // the newly associated virtual handle.
1524ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  TPM_HANDLE LoadHandle(TPM_HANDLE handle) {
1534ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    std::vector<TPM_HANDLE> input_handles = {PERSISTENT_FIRST};
1544ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    std::string command = CreateCommand(TPM_CC_Load,
1554ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        input_handles,
1564ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoAuthorization,
1574ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoParameters);
1584ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    std::vector<TPM_HANDLE> output_handles = {handle};
1594ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    std::string response = CreateResponse(TPM_RC_SUCCESS,
1604ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                          output_handles,
1614ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                          kNoAuthorization,
1624ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                          kNoParameters);
1634ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    EXPECT_CALL(transceiver_, SendCommandAndWait(command))
1644ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn        .WillOnce(Return(response));
1654ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    std::string actual_response = resource_manager_.SendCommandAndWait(command);
1664ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    std::string handle_blob = StripHeader(actual_response);
1674ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    TPM_HANDLE virtual_handle;
1684ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    CHECK_EQ(TPM_RC_SUCCESS, Parse_TPM_HANDLE(&handle_blob, &virtual_handle,
1694ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                              NULL));
1704ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    return virtual_handle;
1714ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
1724ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
1734ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  // Causes the resource manager to evict existing object handles.
1744ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  void EvictObjects() {
1754ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    std::string command = CreateCommand(TPM_CC_Startup,
1764ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoHandles,
1774ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoAuthorization,
1784ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoParameters);
1794ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    std::string response = CreateErrorResponse(TPM_RC_OBJECT_MEMORY);
1804ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    std::string success_response = CreateResponse(TPM_RC_SUCCESS,
1814ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                                  kNoHandles,
1824ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                                  kNoAuthorization,
1834ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                                  kNoParameters);
1844ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    EXPECT_CALL(transceiver_, SendCommandAndWait(_))
1854ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn        .WillOnce(Return(response))
1864ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn        .WillRepeatedly(Return(success_response));
1874ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    EXPECT_CALL(tpm_, ContextSaveSync(_, _, _, _))
1884ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn        .WillRepeatedly(Return(TPM_RC_SUCCESS));
1894ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    EXPECT_CALL(tpm_, FlushContextSync(_, _))
1904ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn        .WillRepeatedly(Return(TPM_RC_SUCCESS));
1914ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    resource_manager_.SendCommandAndWait(command);
1924ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
1934ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
1944ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  // Makes the resource manager aware of a session handle.
1954ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  void StartSession(TPM_HANDLE handle) {
1964ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    std::vector<TPM_HANDLE> input_handles = {1, 2};
1974ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    std::string command = CreateCommand(TPM_CC_StartAuthSession,
1984ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        input_handles,
1994ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoAuthorization,
2004ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoParameters);
2014ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    std::vector<TPM_HANDLE> output_handles = {handle};
2024ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    std::string response = CreateResponse(TPM_RC_SUCCESS,
2034ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                          output_handles,
2044ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                          kNoAuthorization,
2054ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                          kNoParameters);
2064ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    EXPECT_CALL(transceiver_, SendCommandAndWait(command))
2074ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn        .WillOnce(Return(response));
2084ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    std::string actual_response = resource_manager_.SendCommandAndWait(command);
2094ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    ASSERT_EQ(response, actual_response);
2104ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
2114ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
2124ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  // Causes the resource manager to evict an existing session handle.
2134ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  void EvictSession() {
2144ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    std::string command = CreateCommand(TPM_CC_Startup,
2154ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoHandles,
2164ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoAuthorization,
2174ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoParameters);
2184ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    std::string response = CreateErrorResponse(TPM_RC_SESSION_MEMORY);
2194ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    std::string success_response = CreateResponse(TPM_RC_SUCCESS,
2204ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                                  kNoHandles,
2214ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                                  kNoAuthorization,
2224ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                                  kNoParameters);
2234ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    EXPECT_CALL(transceiver_, SendCommandAndWait(_))
2244ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn        .WillOnce(Return(response))
2254ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn        .WillRepeatedly(Return(success_response));
2264ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    EXPECT_CALL(tpm_, ContextSaveSync(_, _, _, _))
2274ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn        .WillOnce(Return(TPM_RC_SUCCESS));
2284ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    resource_manager_.SendCommandAndWait(command);
2294ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
2304ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
2314ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  // Creates a TPMS_CONTEXT with the given sequence field.
2324ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  TPMS_CONTEXT CreateContext(UINT64 sequence) {
2339caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn    TPMS_CONTEXT context;
2349caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn    memset(&context, 0, sizeof(context));
2359caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn    context.sequence = sequence;
2364ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    return context;
2374ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
2384ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
2394ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  // Creates a serialized TPMS_CONTEXT with the given sequence field.
2404ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string CreateContextParameter(UINT64 sequence) {
2414ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    std::string buffer;
2424ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    Serialize_TPMS_CONTEXT(CreateContext(sequence), &buffer);
2434ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    return buffer;
2444ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
2454ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
2464ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn protected:
2474ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  StrictMock<MockTpm> tpm_;
2484ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  TrunksFactoryForTest factory_;
2494ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  StrictMock<MockCommandTransceiver> transceiver_;
2504ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  ResourceManager resource_manager_;
2514ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn};
2524ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
2534ede7fcc1571b23867536b2506900fc3987c2dd5Darren KrahnTEST_F(ResourceManagerTest, BasicPassThrough) {
2544ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string command = CreateCommand(TPM_CC_Startup,
2554ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      kNoHandles,
2564ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      kNoAuthorization,
2574ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      kNoParameters);
2584ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string response = CreateResponse(TPM_RC_SUCCESS,
2594ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoHandles,
2604ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoAuthorization,
2614ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoParameters);
2624ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_CALL(transceiver_, SendCommandAndWait(command))
2634ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      .WillOnce(Return(response));
2644ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string actual_response = resource_manager_.SendCommandAndWait(command);
2654ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_EQ(actual_response, response);
2664ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn}
2674ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
2684ede7fcc1571b23867536b2506900fc3987c2dd5Darren KrahnTEST_F(ResourceManagerTest, BasicPassThroughAsync) {
2694ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string command = CreateCommand(TPM_CC_Startup,
2704ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      kNoHandles,
2714ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      kNoAuthorization,
2724ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      kNoParameters);
2734ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string response = CreateResponse(TPM_RC_SUCCESS,
2744ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoHandles,
2754ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoAuthorization,
2764ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoParameters);
2774ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_CALL(transceiver_, SendCommandAndWait(command))
2784ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      .WillOnce(Return(response));
2794ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string actual_response;
2804ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  CommandTransceiver::ResponseCallback callback =
2814ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      base::Bind(&Assign, &actual_response);
2824ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  resource_manager_.SendCommand(command, callback);
2834ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_EQ(actual_response, response);
2844ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn}
2854ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
2864ede7fcc1571b23867536b2506900fc3987c2dd5Darren KrahnTEST_F(ResourceManagerTest, VirtualHandleOutput) {
2874ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::vector<TPM_HANDLE> input_handles = {PERSISTENT_FIRST};
2884ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string command = CreateCommand(TPM_CC_Load,
2894ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      input_handles,
2904ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      kNoAuthorization,
2914ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      kNoParameters);
2924ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::vector<TPM_HANDLE> output_handles = {kArbitraryObjectHandle};
2934ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string response = CreateResponse(TPM_RC_SUCCESS,
2944ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        output_handles,
2954ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoAuthorization,
2964ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoParameters);
2974ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_CALL(transceiver_, SendCommandAndWait(command))
2984ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      .WillOnce(Return(response));
2994ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string actual_response = resource_manager_.SendCommandAndWait(command);
3004ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_EQ(response.size(), actual_response.size());
3014ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  // We expect the resource manager has replaced the output handle with a
3024ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  // virtual handle (which we can't predict, but it's unlikely to be the same as
3034ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  // the handle emitted by the mock).
3044ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_EQ(GetHeader(response), GetHeader(actual_response));
3054ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_NE(StripHeader(response), StripHeader(actual_response));
3064ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  TPM_HT handle_type = static_cast<TPM_HT>(StripHeader(actual_response)[0]);
3074ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_EQ(TPM_HT_TRANSIENT, handle_type);
3084ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn}
3094ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
3104ede7fcc1571b23867536b2506900fc3987c2dd5Darren KrahnTEST_F(ResourceManagerTest, VirtualHandleInput) {
3114ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  TPM_HANDLE tpm_handle = kArbitraryObjectHandle;
3124ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  TPM_HANDLE virtual_handle = LoadHandle(tpm_handle);
3134ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::vector<TPM_HANDLE> input_handles = {virtual_handle};
3144ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string command = CreateCommand(TPM_CC_Sign,
3154ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      input_handles,
3164ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      kNoAuthorization,
3174ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      kNoParameters);
3184ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  // We expect the resource manager to replace |virtual_handle| with
3194ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  // |tpm_handle|.
3204ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::vector<TPM_HANDLE> expected_input_handles = {tpm_handle};
3214ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string expected_command = CreateCommand(TPM_CC_Sign,
3224ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                               expected_input_handles,
3234ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                               kNoAuthorization,
3244ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                               kNoParameters);
3254ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string response = CreateResponse(TPM_RC_SUCCESS,
3264ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoHandles,
3274ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoAuthorization,
3284ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoParameters);
3294ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_CALL(transceiver_, SendCommandAndWait(expected_command))
3304ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      .WillOnce(Return(response));
3314ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string actual_response = resource_manager_.SendCommandAndWait(command);
3324ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_EQ(response, actual_response);
3334ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn}
3344ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
3354ede7fcc1571b23867536b2506900fc3987c2dd5Darren KrahnTEST_F(ResourceManagerTest, VirtualHandleCleanup) {
3364ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  TPM_HANDLE tpm_handle = kArbitraryObjectHandle;
3374ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  TPM_HANDLE virtual_handle = LoadHandle(tpm_handle);
3384ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string parameters;
3394ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  Serialize_TPM_HANDLE(virtual_handle, &parameters);
3404ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string command = CreateCommand(TPM_CC_FlushContext,
3414ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      kNoHandles,
3424ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      kNoAuthorization,
3434ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      parameters);
3444ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string expected_parameters;
3454ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  Serialize_TPM_HANDLE(tpm_handle, &expected_parameters);
3464ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string expected_command = CreateCommand(TPM_CC_FlushContext,
3474ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                               kNoHandles,
3484ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                               kNoAuthorization,
3494ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                               expected_parameters);
3504ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string response = CreateResponse(TPM_RC_SUCCESS,
3514ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoHandles,
3524ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoAuthorization,
3534ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoParameters);
3544ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_CALL(transceiver_, SendCommandAndWait(expected_command))
3554ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      .WillOnce(Return(response));
3564ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string actual_response = resource_manager_.SendCommandAndWait(command);
3574ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_EQ(response, actual_response);
3584ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  // Now we expect there to be no record of |virtual_handle|.
3594ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::vector<TPM_HANDLE> input_handles = {virtual_handle};
3604ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  command = CreateCommand(TPM_CC_Sign,
3614ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                          input_handles,
3624ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                          kNoAuthorization,
3634ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                          kNoParameters);
3644ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  response = CreateErrorResponse(TPM_RC_HANDLE | kResourceManagerTpmErrorBase);
3654ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  actual_response = resource_manager_.SendCommandAndWait(command);
3664ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_EQ(response, actual_response);
3674ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
3684ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  // Try again but attempt to flush |tpm_handle| instead of |virtual_handle|.
3694ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  virtual_handle = LoadHandle(tpm_handle);
3704ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  parameters.clear();
3714ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  Serialize_TPM_HANDLE(tpm_handle, &parameters);
3724ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  command = CreateCommand(TPM_CC_FlushContext,
3734ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                          kNoHandles,
3744ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                          kNoAuthorization,
3754ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                          parameters);
3764ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  actual_response = resource_manager_.SendCommandAndWait(command);
3774ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  // TPM_RC_HANDLE also expected here.
3784ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_EQ(response, actual_response);
3794ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn}
3804ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
3814ede7fcc1571b23867536b2506900fc3987c2dd5Darren KrahnTEST_F(ResourceManagerTest, VirtualHandleLoadBeforeUse) {
3824ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  TPM_HANDLE tpm_handle = kArbitraryObjectHandle;
3834ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  TPM_HANDLE virtual_handle = LoadHandle(tpm_handle);
3844ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EvictObjects();
3854ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::vector<TPM_HANDLE> input_handles = {virtual_handle};
3864ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string command = CreateCommand(TPM_CC_Sign,
3874ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      input_handles,
3884ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      kNoAuthorization,
3894ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      kNoParameters);
3904ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::vector<TPM_HANDLE> expected_input_handles = {tpm_handle};
3914ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string expected_command = CreateCommand(TPM_CC_Sign,
3924ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                               expected_input_handles,
3934ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                               kNoAuthorization,
3944ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                               kNoParameters);
3954ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string response = CreateResponse(TPM_RC_SUCCESS,
3964ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoHandles,
3974ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoAuthorization,
3984ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoParameters);
3994ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_CALL(tpm_, ContextLoadSync(_, _, _))
4004ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      .WillOnce(Return(TPM_RC_SUCCESS));
4014ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_CALL(transceiver_, SendCommandAndWait(expected_command))
4024ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      .WillOnce(Return(response));
4034ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string actual_response = resource_manager_.SendCommandAndWait(command);
4044ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_EQ(response, actual_response);
4054ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn}
4064ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
4074ede7fcc1571b23867536b2506900fc3987c2dd5Darren KrahnTEST_F(ResourceManagerTest, InvalidVirtualHandle) {
4084ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::vector<TPM_HANDLE> input_handles = {kArbitraryObjectHandle};
4094ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string command = CreateCommand(TPM_CC_Sign,
4104ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      input_handles,
4114ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      kNoAuthorization,
4124ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      kNoParameters);
4134ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string response = CreateErrorResponse(TPM_RC_HANDLE |
4144ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                             kResourceManagerTpmErrorBase);
4154ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string actual_response = resource_manager_.SendCommandAndWait(command);
4164ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_EQ(response, actual_response);
4174ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn}
4184ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
4194ede7fcc1571b23867536b2506900fc3987c2dd5Darren KrahnTEST_F(ResourceManagerTest, SimpleFuzzInputParser) {
4204ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::vector<TPM_HANDLE> handles = {1, 2};
4214ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string parameters = "12345";
4224ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string command = CreateCommand(TPM_CC_StartAuthSession,
4234ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      handles,
4244ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      CreateCommandAuthorization(
4254ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                          kArbitrarySessionHandle,
4264ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                          true),  // continue_session
4274ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      parameters);
4284ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  // We don't care about what happens, only that it doesn't crash.
4294ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_CALL(transceiver_, SendCommandAndWait(_))
4304ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      .WillRepeatedly(Return(CreateErrorResponse(TPM_RC_FAILURE)));
4314ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  ScopedDisableLogging no_logging;
4324ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  for (size_t i = 0; i < command.size(); ++i) {
4334ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    resource_manager_.SendCommandAndWait(command.substr(0, i));
4344ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    resource_manager_.SendCommandAndWait(command.substr(i));
4354ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    std::string fuzzed_command(command);
4364ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    for (uint8_t value = 0; ; value++) {
4374ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      fuzzed_command[i] = static_cast<char>(value);
4384ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      resource_manager_.SendCommandAndWait(fuzzed_command);
4394ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      if (value == 255) {
4404ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn        break;
4414ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      }
4424ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    }
4434ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
4444ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn}
4454ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
4464ede7fcc1571b23867536b2506900fc3987c2dd5Darren KrahnTEST_F(ResourceManagerTest, SimpleFuzzOutputParser) {
4474ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::vector<TPM_HANDLE> handles = {1, 2};
4484ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string parameters = "12345";
4494ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string command = CreateCommand(TPM_CC_StartAuthSession,
4504ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      handles,
4514ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      CreateCommandAuthorization(
4524ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                          kArbitrarySessionHandle,
4534ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                          true),  // continue_session
4544ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      parameters);
4554ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::vector<TPM_HANDLE> out_handles = {3};
4564ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string response = CreateResponse(TPM_RC_SUCCESS,
4574ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        out_handles,
4584ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        CreateResponseAuthorization(
4594ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                            true),  // continue_session
4604ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        parameters);
4614ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string fuzzed_response;
4624ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_CALL(transceiver_, SendCommandAndWait(_))
4634ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      .WillRepeatedly(ReturnPointee(&fuzzed_response));
4644ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  ScopedDisableLogging no_logging;
4654ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  for (size_t i = 0; i < response.size(); ++i) {
4664ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    fuzzed_response = response.substr(0, i);
4674ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    resource_manager_.SendCommandAndWait(command);
4684ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    fuzzed_response = response.substr(i);
4694ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    resource_manager_.SendCommandAndWait(command);
4704ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    fuzzed_response = response;
4714ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    for (uint8_t value = 0; ; value++) {
4724ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      fuzzed_response[i] = static_cast<char>(value);
4734ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      resource_manager_.SendCommandAndWait(command);
4744ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      if (value == 255) {
4754ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn        break;
4764ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      }
4774ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    }
4784ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    fuzzed_response[i] = response[i];
4794ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
4804ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn}
4814ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
4824ede7fcc1571b23867536b2506900fc3987c2dd5Darren KrahnTEST_F(ResourceManagerTest, NewSession) {
4834ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  StartSession(kArbitrarySessionHandle);
4844ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string command = CreateCommand(TPM_CC_Startup,
4854ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      kNoHandles,
4864ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      CreateCommandAuthorization(
4874ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                          kArbitrarySessionHandle,
4884ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                          true),  // continue_session
4894ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      kNoParameters);
4904ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string response = CreateResponse(TPM_RC_SUCCESS,
4914ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoHandles,
4924ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        CreateResponseAuthorization(
4934ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                            true),  // continue_session
4944ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoParameters);
4954ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_CALL(transceiver_, SendCommandAndWait(command))
4964ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      .WillOnce(Return(response));
4974ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string actual_response = resource_manager_.SendCommandAndWait(command);
4984ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_EQ(response, actual_response);
4994ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn}
5004ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
5014ede7fcc1571b23867536b2506900fc3987c2dd5Darren KrahnTEST_F(ResourceManagerTest, DiscontinuedSession) {
5024ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  StartSession(kArbitrarySessionHandle);
5034ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  // Use the session but do not continue.
5044ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string command = CreateCommand(TPM_CC_Startup,
5054ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      kNoHandles,
5064ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      CreateCommandAuthorization(
5074ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                          kArbitrarySessionHandle,
5084ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                          false),  // continue_session
5094ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      kNoParameters);
5104ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string response = CreateResponse(TPM_RC_SUCCESS,
5114ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoHandles,
5124ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        CreateResponseAuthorization(
5134ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                            false),  // continue_session
5144ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoParameters);
5154ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_CALL(transceiver_, SendCommandAndWait(command))
5164ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      .WillOnce(Return(response));
5174ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string actual_response = resource_manager_.SendCommandAndWait(command);
5184ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_EQ(response, actual_response);
5194ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  // Now attempt to use it again and expect a handle error.
5204ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  response = CreateErrorResponse(TPM_RC_HANDLE | kResourceManagerTpmErrorBase);
5214ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  actual_response = resource_manager_.SendCommandAndWait(command);
5224ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_EQ(response, actual_response);
5234ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn}
5244ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
5254ede7fcc1571b23867536b2506900fc3987c2dd5Darren KrahnTEST_F(ResourceManagerTest, LoadSessionBeforeUse) {
5264ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  StartSession(kArbitrarySessionHandle);
5274ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EvictSession();
5284ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string command = CreateCommand(TPM_CC_Startup,
5294ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      kNoHandles,
5304ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      CreateCommandAuthorization(
5314ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                          kArbitrarySessionHandle,
5324ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                          true),  // continue_session
5334ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      kNoParameters);
5344ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string response = CreateResponse(TPM_RC_SUCCESS,
5354ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoHandles,
5364ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        CreateResponseAuthorization(
5374ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                            true),  // continue_session
5384ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoParameters);
5394ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_CALL(transceiver_, SendCommandAndWait(command))
5404ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      .WillOnce(Return(response));
5414ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_CALL(tpm_, ContextLoadSync(_, _, _))
5424ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      .WillOnce(Return(TPM_RC_SUCCESS));
5434ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string actual_response = resource_manager_.SendCommandAndWait(command);
5444ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_EQ(response, actual_response);
5454ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn}
5464ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
5474ede7fcc1571b23867536b2506900fc3987c2dd5Darren KrahnTEST_F(ResourceManagerTest, SessionHandleCleanup) {
5484ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  StartSession(kArbitrarySessionHandle);
5494ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string parameters;
5504ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  Serialize_TPM_HANDLE(kArbitrarySessionHandle, &parameters);
5514ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string command = CreateCommand(TPM_CC_FlushContext,
5524ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      kNoHandles,
5534ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      kNoAuthorization,
5544ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      parameters);
5554ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string response = CreateResponse(TPM_RC_SUCCESS,
5564ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoHandles,
5574ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoAuthorization,
5584ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoParameters);
5594ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_CALL(transceiver_, SendCommandAndWait(command))
5604ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      .WillOnce(Return(response));
5614ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string actual_response = resource_manager_.SendCommandAndWait(command);
5624ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_EQ(response, actual_response);
5634ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  // Now we expect there to be no record of |kArbitrarySessionHandle|.
5644ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  command = CreateCommand(TPM_CC_Startup,
5654ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                          kNoHandles,
5664ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                          CreateCommandAuthorization(
5674ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                              kArbitrarySessionHandle,
5684ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                              true),  // continue_session
5694ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                          kNoParameters);
5704ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  response = CreateErrorResponse(TPM_RC_HANDLE | kResourceManagerTpmErrorBase);
5714ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  actual_response = resource_manager_.SendCommandAndWait(command);
5724ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_EQ(response, actual_response);
5734ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn}
5744ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
5754ede7fcc1571b23867536b2506900fc3987c2dd5Darren KrahnTEST_F(ResourceManagerTest, EvictWhenObjectInUse) {
5764ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  TPM_HANDLE tpm_handle = kArbitraryObjectHandle;
5774ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  TPM_HANDLE virtual_handle = LoadHandle(tpm_handle);
5784ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  TPM_HANDLE tpm_handle2 = kArbitraryObjectHandle + 1;
5794ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  LoadHandle(tpm_handle2);
5804ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::vector<TPM_HANDLE> input_handles = {virtual_handle};
5814ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string command = CreateCommand(TPM_CC_Sign,
5824ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      input_handles,
5834ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      kNoAuthorization,
5844ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      kNoParameters);
5854ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  // Trigger evict logic and verify |input_handles| are not evicted.
5864ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string response = CreateErrorResponse(TPM_RC_OBJECT_MEMORY);
5874ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string success_response = CreateResponse(TPM_RC_SUCCESS,
5884ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                                kNoHandles,
5894ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                                kNoAuthorization,
5904ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                                kNoParameters);
5914ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_CALL(tpm_, ContextSaveSync(tpm_handle2, _, _, _))
5924ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      .WillOnce(Return(TPM_RC_SUCCESS));
5934ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_CALL(tpm_, FlushContextSync(tpm_handle2, _))
5944ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      .WillOnce(Return(TPM_RC_SUCCESS));
5954ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_CALL(transceiver_, SendCommandAndWait(_))
5964ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      .WillOnce(Return(response))
5974ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      .WillRepeatedly(Return(success_response));
5984ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string actual_response = resource_manager_.SendCommandAndWait(command);
5994ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_EQ(success_response, actual_response);
6004ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn}
6014ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
6024ede7fcc1571b23867536b2506900fc3987c2dd5Darren KrahnTEST_F(ResourceManagerTest, EvictWhenSessionInUse) {
6034ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  StartSession(kArbitrarySessionHandle);
6044ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  StartSession(kArbitrarySessionHandle + 1);
6054ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string command = CreateCommand(TPM_CC_Startup,
6064ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      kNoHandles,
6074ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      CreateCommandAuthorization(
6084ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                          kArbitrarySessionHandle,
6094ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                          true),  // continue_session
6104ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      kNoParameters);
6114ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string response = CreateResponse(TPM_RC_SUCCESS,
6124ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoHandles,
6134ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        CreateResponseAuthorization(
6144ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                            true),  // continue_session
6154ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoParameters);
6164ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string error_response = CreateErrorResponse(TPM_RC_SESSION_MEMORY);
6174ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_CALL(transceiver_, SendCommandAndWait(_))
6184ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      .WillOnce(Return(error_response))
6194ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      .WillRepeatedly(Return(response));
6204ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_CALL(tpm_, ContextSaveSync(kArbitrarySessionHandle + 1, _, _, _))
6214ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      .WillOnce(Return(TPM_RC_SUCCESS));
6224ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string actual_response = resource_manager_.SendCommandAndWait(command);
6234ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_EQ(response, actual_response);
6244ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn}
6254ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
6264ede7fcc1571b23867536b2506900fc3987c2dd5Darren KrahnTEST_F(ResourceManagerTest, EvictMultipleObjects) {
6274ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  const int kNumObjects = 10;
6284ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::map<TPM_HANDLE, TPM_HANDLE> handles;
6294ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  for (int i = 0; i < kNumObjects; ++i) {
6304ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    TPM_HANDLE handle = kArbitraryObjectHandle + i;
6314ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    handles[LoadHandle(handle)] = handle;
6324ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
6334ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EvictObjects();
6344ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string response = CreateResponse(TPM_RC_SUCCESS,
6354ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoHandles,
6364ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoAuthorization,
6374ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoParameters);
6384ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_CALL(tpm_, ContextLoadSync(_, _, _))
6394ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      .Times(kNumObjects)
6404ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      .WillRepeatedly(Return(TPM_RC_SUCCESS));
6414ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_CALL(transceiver_, SendCommandAndWait(_))
6424ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      .WillRepeatedly(Return(response));
6434ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  for (auto item : handles) {
6444ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    std::vector<TPM_HANDLE> input_handles = {item.first};
6454ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    std::string command = CreateCommand(TPM_CC_Sign,
6464ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        input_handles,
6474ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoAuthorization,
6484ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoParameters);
6494ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    std::string actual_response = resource_manager_.SendCommandAndWait(command);
6504ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    EXPECT_EQ(response, actual_response);
6514ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
6524ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn}
6534ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
6544ede7fcc1571b23867536b2506900fc3987c2dd5Darren KrahnTEST_F(ResourceManagerTest, EvictMostStaleSession) {
6554ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  StartSession(kArbitrarySessionHandle);
6564ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  StartSession(kArbitrarySessionHandle + 1);
6574ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  StartSession(kArbitrarySessionHandle + 2);
6584ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string response = CreateResponse(TPM_RC_SUCCESS,
6594ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoHandles,
6604ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        CreateResponseAuthorization(
6614ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                            true),  // continue_session
6624ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoParameters);
6634ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_CALL(transceiver_, SendCommandAndWait(_))
6644ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      .WillRepeatedly(Return(response));
6654ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  // Use the first two sessions, leaving the third as the most stale.
6664ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  for (int i = 0; i < 2; ++i) {
6674ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    std::string command = CreateCommand(TPM_CC_Startup,
6684ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoHandles,
6694ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        CreateCommandAuthorization(
6704ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                            kArbitrarySessionHandle + i,
6714ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                            true),  // continue_session
6724ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoParameters);
6734ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    std::string actual_response = resource_manager_.SendCommandAndWait(command);
6744ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    EXPECT_EQ(response, actual_response);
6754ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
6764ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EvictSession();
6774ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  // EvictSession will have messed with the expectations; set them again.
6784ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_CALL(transceiver_, SendCommandAndWait(_))
6794ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      .WillRepeatedly(Return(response));
6804ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  // Use the first two sessions again, expecting no calls to ContextLoad.
6814ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  for (int i = 0; i < 2; ++i) {
6824ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    std::string command = CreateCommand(TPM_CC_Startup,
6834ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoHandles,
6844ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        CreateCommandAuthorization(
6854ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                            kArbitrarySessionHandle + i,
6864ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                            true),  // continue_session
6874ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoParameters);
6884ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    std::string actual_response = resource_manager_.SendCommandAndWait(command);
6894ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    EXPECT_EQ(response, actual_response);
6904ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
6914ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  // Expect a call to ContextLoad if we use the third session.
6924ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string command = CreateCommand(TPM_CC_Startup,
6934ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      kNoHandles,
6944ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      CreateCommandAuthorization(
6954ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                          kArbitrarySessionHandle + 2,
6964ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                          true),  // continue_session
6974ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      kNoParameters);
6984ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_CALL(tpm_, ContextLoadSync(_, _, _))
6994ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      .WillOnce(Return(TPM_RC_SUCCESS));
7004ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string actual_response = resource_manager_.SendCommandAndWait(command);
7014ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_EQ(response, actual_response);
7024ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn}
7034ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
7044ede7fcc1571b23867536b2506900fc3987c2dd5Darren KrahnTEST_F(ResourceManagerTest, HandleContextGap) {
7054ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  const int kNumSessions = 7;
7064ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  const int kNumSessionsToUngap = 4;
7074ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::vector<TPM_HANDLE> expected_ungap_order;
7084ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  for (int i = 0; i < kNumSessions; ++i) {
7094ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    StartSession(kArbitrarySessionHandle + i);
7104ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    if (i < kNumSessionsToUngap) {
7114ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      EvictSession();
7124ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      expected_ungap_order.push_back(kArbitrarySessionHandle + i);
7134ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    }
7144ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
7154ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  // Invoke a context gap.
7164ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string command = CreateCommand(TPM_CC_Startup,
7174ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      kNoHandles,
7184ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      kNoAuthorization,
7194ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      kNoParameters);
7204ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string response = CreateErrorResponse(TPM_RC_CONTEXT_GAP);
7214ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string success_response = CreateResponse(TPM_RC_SUCCESS,
7224ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                                kNoHandles,
7234ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                                kNoAuthorization,
7244ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                                kNoParameters);
7254ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  {
7264ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    InSequence ungap_order;
7274ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    for (auto handle : expected_ungap_order) {
7284ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      EXPECT_CALL(tpm_, ContextLoadSync(_, _, _))
7294ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn          .WillOnce(Return(TPM_RC_SUCCESS));
7304ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      EXPECT_CALL(tpm_, ContextSaveSync(handle, _, _, _))
7314ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn          .WillOnce(Return(TPM_RC_SUCCESS));
7324ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    }
7334ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
7344ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_CALL(transceiver_, SendCommandAndWait(_))
7354ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      .WillOnce(Return(response))
7364ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      .WillRepeatedly(Return(success_response));
7374ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string actual_response = resource_manager_.SendCommandAndWait(command);
7384ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_EQ(success_response, actual_response);
7394ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn}
7404ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
7414ede7fcc1571b23867536b2506900fc3987c2dd5Darren KrahnTEST_F(ResourceManagerTest, ExternalContext) {
7424ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  StartSession(kArbitrarySessionHandle);
7434ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  // Do an external context save.
7444ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::vector<TPM_HANDLE> handles = {kArbitrarySessionHandle};
7454ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string context_save = CreateCommand(TPM_CC_ContextSave,
7464ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                           handles,
7474ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                           kNoAuthorization,
7484ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                           kNoParameters);
7494ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string context_parameter1 = CreateContextParameter(1);
7504ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string context_save_response1 = CreateResponse(TPM_RC_SUCCESS,
7514ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                                      kNoHandles,
7524ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                                      kNoAuthorization,
7534ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                                      context_parameter1);
7544ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_CALL(transceiver_, SendCommandAndWait(context_save))
7554ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      .WillOnce(Return(context_save_response1));
7564ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string actual_response = resource_manager_.SendCommandAndWait(
7574ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      context_save);
7584ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_EQ(context_save_response1, actual_response);
7594ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
7604ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  // Invoke a context gap (which will cause context1 to be mapped to context2).
7619caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn  EXPECT_CALL(tpm_, ContextLoadSync(Field(&TPMS_CONTEXT::sequence, Eq(1u)),
7624ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                    _, _))
7634ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      .WillOnce(Return(TPM_RC_SUCCESS));
7644ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_CALL(tpm_, ContextSaveSync(kArbitrarySessionHandle, _, _, _))
7654ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      .WillOnce(DoAll(SetArgumentPointee<2>(CreateContext(2)),
7664ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                      Return(TPM_RC_SUCCESS)));
7674ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string command = CreateCommand(TPM_CC_Startup,
7684ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      kNoHandles,
7694ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      kNoAuthorization,
7704ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      kNoParameters);
7714ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string response = CreateErrorResponse(TPM_RC_CONTEXT_GAP);
7724ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string success_response = CreateResponse(TPM_RC_SUCCESS,
7734ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                                kNoHandles,
7744ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                                kNoAuthorization,
7754ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                                kNoParameters);
7764ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_CALL(transceiver_, SendCommandAndWait(command))
7774ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      .WillOnce(Return(response))
7784ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      .WillOnce(Return(success_response));
7794ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  actual_response = resource_manager_.SendCommandAndWait(command);
7804ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_EQ(success_response, actual_response);
7814ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
7824ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  // Now load external context1 and expect an actual load of context2.
7834ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string context_load1 = CreateCommand(TPM_CC_ContextLoad,
7844ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                            kNoHandles,
7854ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                            kNoAuthorization,
7864ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                            context_parameter1);
7874ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string context_load2 = CreateCommand(TPM_CC_ContextLoad,
7884ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                            kNoHandles,
7894ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                            kNoAuthorization,
7904ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                            CreateContextParameter(2));
7914ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string context_load_response = CreateResponse(TPM_RC_SUCCESS,
7924ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                                     handles,
7934ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                                     kNoAuthorization,
7944ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                                     kNoParameters);
7954ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_CALL(transceiver_, SendCommandAndWait(context_load2))
7964ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      .WillOnce(Return(context_load_response));
7974ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  actual_response = resource_manager_.SendCommandAndWait(context_load1);
7984ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_EQ(context_load_response, actual_response);
7994ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn}
8004ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
8014ede7fcc1571b23867536b2506900fc3987c2dd5Darren KrahnTEST_F(ResourceManagerTest, NestedFailures) {
8024ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  // The scenario being tested is when a command results in a warning to be
8034ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  // handled by the resource manager, and in the process of handling the first
8044ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  // warning another warning occurs which should be handled by the resource
8054ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  // manager, etc..
8064ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  for (int i = 0; i < 3; ++i) {
8074ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    LoadHandle(kArbitraryObjectHandle + i);
8084ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
8094ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EvictObjects();
8104ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  for (int i = 3; i < 6; ++i) {
8114ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    LoadHandle(kArbitraryObjectHandle + i);
8124ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
8134ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  for (int i = 0; i < 10; ++i) {
8144ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    StartSession(kArbitrarySessionHandle + i);
8154ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    EvictSession();
8164ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
8174ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  for (int i = 10; i < 20; ++i) {
8184ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    StartSession(kArbitrarySessionHandle + i);
8194ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
8204ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string error_response = CreateErrorResponse(TPM_RC_MEMORY);
8214ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_CALL(transceiver_, SendCommandAndWait(_))
8224ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      .WillRepeatedly(Return(error_response));
8234ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  // The TPM_RC_MEMORY will result in a context save, make that fail too.
8244ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_CALL(tpm_, ContextSaveSync(_, _, _, _))
8254ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      .WillRepeatedly(Return(TPM_RC_CONTEXT_GAP));
8264ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  // The TPM_RC_CONTEXT_GAP will result in a context load.
8274ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_CALL(tpm_, ContextLoadSync(_, _, _))
8284ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      .WillRepeatedly(Return(TPM_RC_SESSION_HANDLES));
8294ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  // The TPM_RC_SESSION_HANDLES will result in a context flush.
8304ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_CALL(tpm_, FlushContextSync(_, _))
8314ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      .WillRepeatedly(Return(TPM_RC_SESSION_MEMORY));
8324ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  // The resource manager should not handle the same warning twice so we expect
8334ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  // the error of the original call to bubble up.
8344ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string command = CreateCommand(TPM_CC_Startup,
8354ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      kNoHandles,
8364ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      kNoAuthorization,
8374ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      kNoParameters);
8384ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string response = resource_manager_.SendCommandAndWait(command);
8394ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_EQ(error_response, response);
8404ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn}
8414ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
8424ede7fcc1571b23867536b2506900fc3987c2dd5Darren KrahnTEST_F(ResourceManagerTest, OutOfMemory) {
8434ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string error_response = CreateErrorResponse(TPM_RC_MEMORY);
8444ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_CALL(transceiver_, SendCommandAndWait(_))
8454ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      .WillRepeatedly(Return(error_response));
8464ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string command = CreateCommand(TPM_CC_Startup,
8474ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      kNoHandles,
8484ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      kNoAuthorization,
8494ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      kNoParameters);
8504ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string response = resource_manager_.SendCommandAndWait(command);
8514ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_EQ(error_response, response);
8524ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn}
8534ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
8544ede7fcc1571b23867536b2506900fc3987c2dd5Darren KrahnTEST_F(ResourceManagerTest, ReentrantFixGap) {
8554ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  for (int i = 0; i < 3; ++i) {
8564ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    StartSession(kArbitrarySessionHandle + i);
8574ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    EvictSession();
8584ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
8594ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  for (int i = 3; i < 6; ++i) {
8604ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    StartSession(kArbitrarySessionHandle + i);
8614ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
8624ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string error_response = CreateErrorResponse(TPM_RC_CONTEXT_GAP);
8634ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_CALL(transceiver_, SendCommandAndWait(_))
8644ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      .WillRepeatedly(Return(error_response));
8654ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_CALL(tpm_, ContextSaveSync(_, _, _, _))
8664ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      .WillRepeatedly(Return(TPM_RC_CONTEXT_GAP));
8674ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_CALL(tpm_, ContextLoadSync(_, _, _))
8684ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      .WillOnce(Return(TPM_RC_CONTEXT_GAP))
8694ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      .WillRepeatedly(Return(TPM_RC_SUCCESS));
8704ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string command = CreateCommand(TPM_CC_Startup,
8714ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      kNoHandles,
8724ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      kNoAuthorization,
8734ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      kNoParameters);
8744ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string response = resource_manager_.SendCommandAndWait(command);
8754ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_EQ(error_response, response);
8764ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn}
8774ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
8784ede7fcc1571b23867536b2506900fc3987c2dd5Darren KrahnTEST_F(ResourceManagerTest, PasswordAuthorization) {
8794ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string command = CreateCommand(TPM_CC_Startup,
8804ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      kNoHandles,
8814ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      CreateCommandAuthorization(
8824ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                          TPM_RS_PW,
8834ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                          false),  // continue_session
8844ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      kNoParameters);
8854ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string response = CreateResponse(TPM_RC_SUCCESS,
8864ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoHandles,
8874ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        CreateResponseAuthorization(
8884ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                            false),  // continue_session
8894ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                        kNoParameters);
8904ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_CALL(transceiver_, SendCommandAndWait(command))
8914ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      .WillOnce(Return(response));
8924ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string actual_response = resource_manager_.SendCommandAndWait(command);
8934ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  EXPECT_EQ(response, actual_response);
8944ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn}
8954ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
8964ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn}  // namespace trunks
897