tpm_generated_test.cc revision 6a5f9fd320f2bd202653d09bad15a75474d49360
187496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn// Copyright 2014 The Chromium OS Authors. All rights reserved.
287496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn// Use of this source code is governed by a BSD-style license that can be
387496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn// found in the LICENSE file.
487496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn
587496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn// Note: These tests are not generated. They test generated code.
687496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn
7a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn#include <base/bind.h>
8a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn#include <base/callback.h>
9a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn#include <base/message_loop/message_loop.h>
10a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn#include <base/run_loop.h>
1187496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn#include <gtest/gtest.h>
1287496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn
13a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn#include "trunks/mock_authorization_delegate.h"
14a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn#include "trunks/mock_command_transceiver.h"
1587496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn#include "trunks/tpm_generated.h"
1687496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn
17a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahnusing testing::_;
18a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahnusing testing::DoAll;
19a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahnusing testing::Invoke;
20a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahnusing testing::Return;
21a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahnusing testing::SetArgPointee;
22a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahnusing testing::StrictMock;
23a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahnusing testing::WithArg;
24a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn
2587496dd0090ac4f9188297e05573207db41ba2b6Darren Krahnnamespace trunks {
2687496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn
27a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn// This test is designed to get good coverage of the different types of code
28a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn// generated for serializing and parsing structures / unions / typedefs.
2987496dd0090ac4f9188297e05573207db41ba2b6Darren KrahnTEST(GeneratorTest, SerializeParseStruct) {
3087496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn  TPM2B_CREATION_DATA data;
3187496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn  memset(&data, 0, sizeof(TPM2B_CREATION_DATA));
3287496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn  data.creation_data.pcr_select.count = 1;
3387496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn  data.creation_data.pcr_select.pcr_selections[0].hash = TPM_ALG_SHA256;
3487496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn  data.creation_data.pcr_select.pcr_selections[0].sizeof_select = 1;
3587496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn  data.creation_data.pcr_select.pcr_selections[0].pcr_select[0] = 0;
3687496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn  data.creation_data.pcr_digest.size = 2;
3787496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn  data.creation_data.locality = 0;
3887496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn  data.creation_data.parent_name_alg = TPM_ALG_SHA256;
3987496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn  data.creation_data.parent_name.size = 3;
4087496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn  data.creation_data.parent_qualified_name.size = 4;
4187496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn  data.creation_data.outside_info.size = 5;
4287496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn  std::string buffer;
4387496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn  TPM_RC rc = Serialize_TPM2B_CREATION_DATA(data, &buffer);
4487496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn  ASSERT_EQ(TPM_RC_SUCCESS, rc);
4587496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn  EXPECT_EQ(35, buffer.size());
4687496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn  TPM2B_CREATION_DATA data2;
4787496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn  memset(&data2, 0, sizeof(TPM2B_CREATION_DATA));
4887496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn  std::string buffer_before = buffer;
4987496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn  std::string buffer_parsed;
5087496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn  rc = Parse_TPM2B_CREATION_DATA(&buffer, &data2, &buffer_parsed);
5187496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn  ASSERT_EQ(TPM_RC_SUCCESS, rc);
5287496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn  EXPECT_EQ(0, buffer.size());
5387496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn  EXPECT_EQ(buffer_before, buffer_parsed);
5487496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn  EXPECT_EQ(0, memcmp(&data, &data2, sizeof(TPM2B_CREATION_DATA)));
5587496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn}
5687496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn
5758a6ad9e4e634f7dbafaea963ad43076e0ed1733Darren KrahnTEST(GeneratorTest, SerializeBufferOverflow) {
5858a6ad9e4e634f7dbafaea963ad43076e0ed1733Darren Krahn  TPM2B_MAX_BUFFER value;
5958a6ad9e4e634f7dbafaea963ad43076e0ed1733Darren Krahn  value.size = arraysize(value.buffer) + 1;
6058a6ad9e4e634f7dbafaea963ad43076e0ed1733Darren Krahn  std::string tmp;
6158a6ad9e4e634f7dbafaea963ad43076e0ed1733Darren Krahn  EXPECT_EQ(TPM_RC_INSUFFICIENT, Serialize_TPM2B_MAX_BUFFER(value, &tmp));
6258a6ad9e4e634f7dbafaea963ad43076e0ed1733Darren Krahn}
6358a6ad9e4e634f7dbafaea963ad43076e0ed1733Darren Krahn
6458a6ad9e4e634f7dbafaea963ad43076e0ed1733Darren KrahnTEST(GeneratorTest, ParseBufferOverflow) {
6558a6ad9e4e634f7dbafaea963ad43076e0ed1733Darren Krahn  TPM2B_MAX_BUFFER tmp;
6658a6ad9e4e634f7dbafaea963ad43076e0ed1733Darren Krahn  // Case 1: Sufficient source but overflow the destination.
6758a6ad9e4e634f7dbafaea963ad43076e0ed1733Darren Krahn  std::string malformed1 = "\x10\x00";
6858a6ad9e4e634f7dbafaea963ad43076e0ed1733Darren Krahn  malformed1 += std::string(0x1000, 'A');
6958a6ad9e4e634f7dbafaea963ad43076e0ed1733Darren Krahn  ASSERT_GT(0x1000, sizeof(tmp.buffer));
7058a6ad9e4e634f7dbafaea963ad43076e0ed1733Darren Krahn  EXPECT_EQ(TPM_RC_INSUFFICIENT,
7158a6ad9e4e634f7dbafaea963ad43076e0ed1733Darren Krahn            Parse_TPM2B_MAX_BUFFER(&malformed1, &tmp, NULL));
7258a6ad9e4e634f7dbafaea963ad43076e0ed1733Darren Krahn  // Case 2: Sufficient destination but overflow the source.
7358a6ad9e4e634f7dbafaea963ad43076e0ed1733Darren Krahn  std::string malformed2 = "\x00\x01";
7458a6ad9e4e634f7dbafaea963ad43076e0ed1733Darren Krahn  EXPECT_EQ(TPM_RC_INSUFFICIENT,
7558a6ad9e4e634f7dbafaea963ad43076e0ed1733Darren Krahn            Parse_TPM2B_MAX_BUFFER(&malformed2, &tmp, NULL));
7658a6ad9e4e634f7dbafaea963ad43076e0ed1733Darren Krahn}
7758a6ad9e4e634f7dbafaea963ad43076e0ed1733Darren Krahn
786a5f9fd320f2bd202653d09bad15a75474d49360Darren KrahnTEST(GeneratorTest, SynchronousCommand) {
796a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn  // A hand-rolled TPM2_Startup command.
806a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn  std::string expected_command("\x80\x01"          // tag=TPM_ST_NO_SESSIONS
816a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn                               "\x00\x00\x00\x0C"  // size=12
826a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn                               "\x00\x00\x01\x44"  // code=TPM_CC_Startup
836a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn                               "\x00\x00",         // param=TPM_SU_CLEAR
846a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn                               12);
856a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn  std::string command_response("\x80\x01"           // tag=TPM_ST_NO_SESSIONS
866a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn                               "\x00\x00\x00\x0A"   // size=10
876a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn                               "\x00\x00\x00\x00",  // code=TPM_RC_SUCCESS
886a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn                               10);
896a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn  StrictMock<MockCommandTransceiver> transceiver;
906a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn  EXPECT_CALL(transceiver, SendCommandAndWait(expected_command, _))
916a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn    .WillOnce(DoAll(SetArgPointee<1>(command_response),
926a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn                    Return(TPM_RC_SUCCESS)));
936a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn  StrictMock<MockAuthorizationDelegate> authorization;
946a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn  EXPECT_CALL(authorization, GetCommandAuthorization(_, _))
956a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn    .WillOnce(Return(true));
966a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn  Tpm tpm(&transceiver);
976a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn  EXPECT_EQ(TPM_RC_SUCCESS, tpm.StartupSync(TPM_SU_CLEAR, &authorization));
986a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn}
996a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn
1006a5f9fd320f2bd202653d09bad15a75474d49360Darren KrahnTEST(GeneratorTest, SynchronousCommandWithError) {
1016a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn  // A hand-rolled TPM2_Startup command.
1026a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn  std::string expected_command("\x80\x01"          // tag=TPM_ST_NO_SESSIONS
1036a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn                               "\x00\x00\x00\x0C"  // size=12
1046a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn                               "\x00\x00\x01\x44"  // code=TPM_CC_Startup
1056a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn                               "\x00\x00",         // param=TPM_SU_CLEAR
1066a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn                               12);
1076a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn  std::string command_response("\x80\x01"           // tag=TPM_ST_NO_SESSIONS
1086a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn                               "\x00\x00\x00\x0A"   // size=10
1096a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn                               "\x00\x00\x01\x01",  // code=TPM_RC_FAILURE
1106a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn                               10);
1116a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn  StrictMock<MockCommandTransceiver> transceiver;
1126a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn  EXPECT_CALL(transceiver, SendCommandAndWait(expected_command, _))
1136a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn    .WillOnce(DoAll(SetArgPointee<1>(command_response),
1146a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn                    Return(TPM_RC_SUCCESS)));
1156a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn  StrictMock<MockAuthorizationDelegate> authorization;
1166a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn  EXPECT_CALL(authorization, GetCommandAuthorization(_, _))
1176a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn    .WillOnce(Return(true));
1186a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn  Tpm tpm(&transceiver);
1196a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn  EXPECT_EQ(TPM_RC_FAILURE, tpm.StartupSync(TPM_SU_CLEAR, &authorization));
1206a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn}
1216a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn
1226a5f9fd320f2bd202653d09bad15a75474d49360Darren KrahnTEST(GeneratorTest, SynchronousCommandWithTransceiverError) {
1236a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn  // A hand-rolled TPM2_Startup command.
1246a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn  std::string expected_command("\x80\x01"          // tag=TPM_ST_NO_SESSIONS
1256a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn                               "\x00\x00\x00\x0C"  // size=12
1266a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn                               "\x00\x00\x01\x44"  // code=TPM_CC_Startup
1276a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn                               "\x00\x00",         // param=TPM_SU_CLEAR
1286a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn                               12);
1296a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn  std::string command_response("\x80\x01"           // tag=TPM_ST_NO_SESSIONS
1306a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn                               "\x00\x00\x00\x0A"   // size=10
1316a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn                               "\x00\x00\x00\x00",  // code=TPM_RC_SUCCESS
1326a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn                               10);
1336a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn  StrictMock<MockCommandTransceiver> transceiver;
1346a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn  EXPECT_CALL(transceiver, SendCommandAndWait(expected_command, _))
1356a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn    .WillOnce(DoAll(SetArgPointee<1>(command_response),
1366a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn                    Return(TPM_RC_FAILURE)));
1376a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn  StrictMock<MockAuthorizationDelegate> authorization;
1386a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn  EXPECT_CALL(authorization, GetCommandAuthorization(_, _))
1396a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn    .WillOnce(Return(true));
1406a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn  Tpm tpm(&transceiver);
1416a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn  EXPECT_EQ(TPM_RC_FAILURE, tpm.StartupSync(TPM_SU_CLEAR, &authorization));
1426a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn}
1436a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn
144a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn// A fixture for asynchronous command flow tests.
145a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahnclass CommandFlowTest : public testing::Test {
146a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn public:
147a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  CommandFlowTest() : response_code_(TPM_RC_SUCCESS) {}
148a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  virtual ~CommandFlowTest() {}
149a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn
150a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  void StartupCallback(TPM_RC response_code) {
151a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn    response_code_ = response_code;
152a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  }
153a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn
154a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  void CertifyCallback(TPM_RC response_code,
1556a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn                       const TPM2B_ATTEST& certify_info,
1566a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn                       const TPMT_SIGNATURE& signature) {
157a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn    response_code_ = response_code;
158a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn    signed_data_ = StringFrom_TPM2B_ATTEST(certify_info);
159a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn    signature_ = StringFrom_TPM2B_PUBLIC_KEY_RSA(
160a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn        signature.signature.rsassa.sig);
161a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  }
162a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn
163a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn protected:
164a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  void Run() {
165a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn    base::RunLoop run_loop;
166a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn    run_loop.RunUntilIdle();
167a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  }
168a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn
169a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  base::MessageLoop message_loop_;
170a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  TPM_RC response_code_;
171a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  std::string signature_;
172a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  std::string signed_data_;
173a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn};
174a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn
175a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn// A functor for posting command responses. This is different than invoking the
176a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn// callback directly (e.g. via InvokeArgument) in that the original call will
177a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn// return before the response callback is invoked. This more closely matches how
178a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn// this code is expected to work when integrated.
179a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahnclass PostResponse {
180a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn public:
181a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  explicit PostResponse(const std::string& response) : response_(response) {}
182a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  void operator() (const base::Callback<void(const std::string&)>& callback) {
183a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn    base::MessageLoop::current()->PostTask(FROM_HERE,
184a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn                                           base::Bind(callback, response_));
185a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  }
186a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn
187a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn private:
188a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  std::string response_;
189a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn};
190a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn
191a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn// A functor to handle fake encryption / decryption of parameters.
192a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahnclass Encryptor {
193a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn public:
194a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  Encryptor(const std::string& expected_input, const std::string& output)
195a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn      : expected_input_(expected_input),
196a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn        output_(output) {}
197a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  bool operator() (std::string* value) {
198a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn    EXPECT_EQ(expected_input_, *value);
199a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn    value->assign(output_);
200a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn    return true;
201a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  }
202a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn
203a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn private:
204a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  std::string expected_input_;
205a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  std::string output_;
206a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn};
207a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn
208a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren KrahnTEST_F(CommandFlowTest, SimpleCommandFlow) {
20958a6ad9e4e634f7dbafaea963ad43076e0ed1733Darren Krahn  // A hand-rolled TPM2_Startup command.
210a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  std::string expected_command("\x80\x01"          // tag=TPM_ST_NO_SESSIONS
211a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn                               "\x00\x00\x00\x0C"  // size=12
212a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn                               "\x00\x00\x01\x44"  // code=TPM_CC_Startup
213a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn                               "\x00\x00",         // param=TPM_SU_CLEAR
214a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn                               12);
215a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  std::string command_response("\x80\x01"           // tag=TPM_ST_NO_SESSIONS
216a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn                               "\x00\x00\x00\x0A"   // size=10
217a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn                               "\x00\x00\x00\x00",  // code=TPM_RC_SUCCESS
218a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn                               10);
219a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  StrictMock<MockCommandTransceiver> transceiver;
220a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  EXPECT_CALL(transceiver, SendCommand(expected_command, _))
221a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn    .WillOnce(WithArg<1>(Invoke(PostResponse(command_response))));
222a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  StrictMock<MockAuthorizationDelegate> authorization;
223a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  EXPECT_CALL(authorization, GetCommandAuthorization(_, _))
224a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn    .WillOnce(Return(true));
225a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  Tpm tpm(&transceiver);
226a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  response_code_ = TPM_RC_FAILURE;
227a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  tpm.Startup(TPM_SU_CLEAR,
228a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn              &authorization,
229a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn              base::Bind(&CommandFlowTest::StartupCallback,
230a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn                         base::Unretained(this)));
231a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  Run();
232a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  EXPECT_EQ(TPM_RC_SUCCESS, response_code_);
233a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn}
234a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn
235a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren KrahnTEST_F(CommandFlowTest, SimpleCommandFlowWithError) {
236a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  // A hand-rolled TPM2_Startup command.
237a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  std::string expected_command("\x80\x01"          // tag=TPM_ST_NO_SESSIONS
238a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn                               "\x00\x00\x00\x0C"  // size=12
239a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn                               "\x00\x00\x01\x44"  // code=TPM_CC_Startup
240a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn                               "\x00\x00",         // param=TPM_SU_CLEAR
241a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn                               12);
242a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  std::string command_response("\x80\x01"           // tag=TPM_ST_NO_SESSIONS
243a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn                               "\x00\x00\x00\x0A"   // size=10
244a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn                               "\x00\x00\x01\x01",  // code=TPM_RC_FAILURE
245a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn                               10);
246a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  StrictMock<MockCommandTransceiver> transceiver;
247a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  EXPECT_CALL(transceiver, SendCommand(expected_command, _))
248a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn    .WillOnce(WithArg<1>(Invoke(PostResponse(command_response))));
249a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  StrictMock<MockAuthorizationDelegate> authorization;
250a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  EXPECT_CALL(authorization, GetCommandAuthorization(_, _))
251a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn    .WillOnce(Return(true));
252a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  Tpm tpm(&transceiver);
253a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  tpm.Startup(TPM_SU_CLEAR,
254a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn              &authorization,
255a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn              base::Bind(&CommandFlowTest::StartupCallback,
256a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn                         base::Unretained(this)));
257a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  Run();
258a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  EXPECT_EQ(TPM_RC_FAILURE, response_code_);
259a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn}
260a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn
261a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn// This test is designed to get good coverage of the different types of code
262a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn// generated for command / response processing. It covers:
263a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn// - input handles
264a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn// - authorization
265a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn// - multiple input and output parameters
266a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn// - parameter encryption and decryption
267a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren KrahnTEST_F(CommandFlowTest, FullCommandFlow) {
268a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  // A hand-rolled TPM2_Certify command.
269a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  std::string auth_in(10, 'A');
270a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  std::string auth_out(20, 'B');
271a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  std::string user_data("\x00\x0C" "ct_user_data", 14);
272a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  std::string scheme("\x00\x10", 2);  // scheme=TPM_ALG_NULL
273a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  std::string signed_data("\x00\x0E" "ct_signed_data", 16);
274a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  std::string signature("\x00\x14"    // sig_scheme=RSASSA
275a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn                        "\x00\x0B"    // hash_scheme=SHA256
276a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn                        "\x00\x09"    // signature size
277a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn                        "signature",  // signature bytes
278a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn                        15);
279a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  std::string expected_command("\x80\x02"           // tag=TPM_ST_SESSIONS
280a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn                               "\x00\x00\x00\x30"   // size=48
281a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn                               "\x00\x00\x01\x48"   // code=TPM_CC_Certify
282a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn                               "\x11\x22\x33\x44"   // @objectHandle
283a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn                               "\x55\x66\x77\x88"   // @signHandle
284a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn                               "\x00\x00\x00\x0A",  // auth_size=10
285a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn                               22);
286a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  expected_command += auth_in + user_data + scheme;
287a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  std::string command_response("\x80\x02"           // tag=TPM_ST_SESSIONS
288a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn                               "\x00\x00\x00\x41"   // size=65
289a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn                               "\x00\x00\x00\x00"   // code=TPM_RC_SUCCESS
290a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn                               "\x00\x00\x00\x1F",  // param_size=31
291a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn                               14);
292a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  command_response += signed_data + signature + auth_out;
293a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn
294a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  StrictMock<MockCommandTransceiver> transceiver;
295a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  EXPECT_CALL(transceiver, SendCommand(expected_command, _))
296a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn    .WillOnce(WithArg<1>(Invoke(PostResponse(command_response))));
297a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  StrictMock<MockAuthorizationDelegate> authorization;
298a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  EXPECT_CALL(authorization, GetCommandAuthorization(_, _))
299a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn    .WillOnce(DoAll(SetArgPointee<1>(auth_in), Return(true)));
300a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  EXPECT_CALL(authorization, CheckResponseAuthorization(_, auth_out))
301a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn    .WillOnce(Return(true));
302a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  EXPECT_CALL(authorization, EncryptCommandParameter(_))
303a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn    .WillOnce(Invoke(Encryptor("pt_user_data", "ct_user_data")));
304a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  EXPECT_CALL(authorization, DecryptResponseParameter(_))
305a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn    .WillOnce(Invoke(Encryptor("ct_signed_data", "pt_signed_data")));
306a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn
307a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  TPMT_SIG_SCHEME null_scheme;
308a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  null_scheme.scheme = TPM_ALG_NULL;
309a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  null_scheme.details.rsassa.hash_alg = TPM_ALG_SHA256;
310a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  Tpm tpm(&transceiver);
311a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  tpm.Certify(0x11223344u, "object_handle",
312a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn              0x55667788u, "sign_handle",
313a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn              Make_TPM2B_DATA("pt_user_data"),
314a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn              null_scheme,
315a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn              &authorization,
316a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn              base::Bind(&CommandFlowTest::CertifyCallback,
317a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn                         base::Unretained(this)));
318a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  Run();
319a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  ASSERT_EQ(TPM_RC_SUCCESS, response_code_);
320a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  EXPECT_EQ("pt_signed_data", signed_data_);
321a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  EXPECT_EQ("signature", signature_);
322a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn}
323a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn
32487496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn}  // namespace trunks
325