1bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi//
2bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// Copyright (C) 2014 The Android Open Source Project
3bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi//
4bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// Licensed under the Apache License, Version 2.0 (the "License");
5bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// you may not use this file except in compliance with the License.
6bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// You may obtain a copy of the License at
7bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi//
8bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi//      http://www.apache.org/licenses/LICENSE-2.0
9bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi//
10bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// Unless required by applicable law or agreed to in writing, software
11bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// distributed under the License is distributed on an "AS IS" BASIS,
12bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// See the License for the specific language governing permissions and
14bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// limitations under the License.
15bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi//
1687496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn
1787496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn// Note: These tests are not generated. They test generated code.
1887496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn
19a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn#include <base/bind.h>
20a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn#include <base/callback.h>
21a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn#include <base/message_loop/message_loop.h>
22a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn#include <base/run_loop.h>
2387496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn#include <gtest/gtest.h>
2487496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn
25a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn#include "trunks/mock_authorization_delegate.h"
26a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn#include "trunks/mock_command_transceiver.h"
2787496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn#include "trunks/tpm_generated.h"
2887496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn
29a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahnusing testing::_;
30a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahnusing testing::DoAll;
31a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahnusing testing::Invoke;
32a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahnusing testing::Return;
33a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahnusing testing::SetArgPointee;
34a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahnusing testing::StrictMock;
35a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahnusing testing::WithArg;
36a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn
3787496dd0090ac4f9188297e05573207db41ba2b6Darren Krahnnamespace trunks {
3887496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn
39a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn// This test is designed to get good coverage of the different types of code
40a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn// generated for serializing and parsing structures / unions / typedefs.
4187496dd0090ac4f9188297e05573207db41ba2b6Darren KrahnTEST(GeneratorTest, SerializeParseStruct) {
4287496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn  TPM2B_CREATION_DATA data;
4387496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn  memset(&data, 0, sizeof(TPM2B_CREATION_DATA));
4487496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn  data.creation_data.pcr_select.count = 1;
4587496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn  data.creation_data.pcr_select.pcr_selections[0].hash = TPM_ALG_SHA256;
4687496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn  data.creation_data.pcr_select.pcr_selections[0].sizeof_select = 1;
4787496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn  data.creation_data.pcr_select.pcr_selections[0].pcr_select[0] = 0;
4887496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn  data.creation_data.pcr_digest.size = 2;
4987496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn  data.creation_data.locality = 0;
5087496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn  data.creation_data.parent_name_alg = TPM_ALG_SHA256;
5187496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn  data.creation_data.parent_name.size = 3;
5287496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn  data.creation_data.parent_qualified_name.size = 4;
5387496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn  data.creation_data.outside_info.size = 5;
5487496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn  std::string buffer;
5587496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn  TPM_RC rc = Serialize_TPM2B_CREATION_DATA(data, &buffer);
5687496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn  ASSERT_EQ(TPM_RC_SUCCESS, rc);
579caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn  EXPECT_EQ(35u, buffer.size());
5887496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn  TPM2B_CREATION_DATA data2;
5987496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn  memset(&data2, 0, sizeof(TPM2B_CREATION_DATA));
6087496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn  std::string buffer_before = buffer;
6187496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn  std::string buffer_parsed;
6287496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn  rc = Parse_TPM2B_CREATION_DATA(&buffer, &data2, &buffer_parsed);
6387496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn  ASSERT_EQ(TPM_RC_SUCCESS, rc);
649caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn  EXPECT_EQ(0u, buffer.size());
6587496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn  EXPECT_EQ(buffer_before, buffer_parsed);
66434cfb322d09c125018fc0864f42d36dff3014e6Darren Krahn  EXPECT_EQ(buffer_before.size() - 2, data2.size);
674dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn  EXPECT_EQ(0, memcmp(&data.creation_data, &data2.creation_data,
68434cfb322d09c125018fc0864f42d36dff3014e6Darren Krahn                      sizeof(TPMS_CREATION_DATA)));
6987496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn}
7087496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn
7158a6ad9e4e634f7dbafaea963ad43076e0ed1733Darren KrahnTEST(GeneratorTest, SerializeBufferOverflow) {
7258a6ad9e4e634f7dbafaea963ad43076e0ed1733Darren Krahn  TPM2B_MAX_BUFFER value;
7358a6ad9e4e634f7dbafaea963ad43076e0ed1733Darren Krahn  value.size = arraysize(value.buffer) + 1;
7458a6ad9e4e634f7dbafaea963ad43076e0ed1733Darren Krahn  std::string tmp;
7558a6ad9e4e634f7dbafaea963ad43076e0ed1733Darren Krahn  EXPECT_EQ(TPM_RC_INSUFFICIENT, Serialize_TPM2B_MAX_BUFFER(value, &tmp));
7658a6ad9e4e634f7dbafaea963ad43076e0ed1733Darren Krahn}
7758a6ad9e4e634f7dbafaea963ad43076e0ed1733Darren Krahn
7858a6ad9e4e634f7dbafaea963ad43076e0ed1733Darren KrahnTEST(GeneratorTest, ParseBufferOverflow) {
7958a6ad9e4e634f7dbafaea963ad43076e0ed1733Darren Krahn  TPM2B_MAX_BUFFER tmp;
8058a6ad9e4e634f7dbafaea963ad43076e0ed1733Darren Krahn  // Case 1: Sufficient source but overflow the destination.
8158a6ad9e4e634f7dbafaea963ad43076e0ed1733Darren Krahn  std::string malformed1 = "\x10\x00";
8258a6ad9e4e634f7dbafaea963ad43076e0ed1733Darren Krahn  malformed1 += std::string(0x1000, 'A');
839caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn  ASSERT_GT(0x1000u, sizeof(tmp.buffer));
8458a6ad9e4e634f7dbafaea963ad43076e0ed1733Darren Krahn  EXPECT_EQ(TPM_RC_INSUFFICIENT,
85c04decde2a6e9b74395f402818852e752534254bUtkarsh Sanghi            Parse_TPM2B_MAX_BUFFER(&malformed1, &tmp, nullptr));
8658a6ad9e4e634f7dbafaea963ad43076e0ed1733Darren Krahn  // Case 2: Sufficient destination but overflow the source.
8758a6ad9e4e634f7dbafaea963ad43076e0ed1733Darren Krahn  std::string malformed2 = "\x00\x01";
8858a6ad9e4e634f7dbafaea963ad43076e0ed1733Darren Krahn  EXPECT_EQ(TPM_RC_INSUFFICIENT,
89c04decde2a6e9b74395f402818852e752534254bUtkarsh Sanghi            Parse_TPM2B_MAX_BUFFER(&malformed2, &tmp, nullptr));
9058a6ad9e4e634f7dbafaea963ad43076e0ed1733Darren Krahn}
9158a6ad9e4e634f7dbafaea963ad43076e0ed1733Darren Krahn
926a5f9fd320f2bd202653d09bad15a75474d49360Darren KrahnTEST(GeneratorTest, SynchronousCommand) {
936a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn  // A hand-rolled TPM2_Startup command.
944dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn  std::string expected_command(
954dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x80\x01"          // tag=TPM_ST_NO_SESSIONS
964dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x00\x00\x0C"  // size=12
974dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x00\x01\x44"  // code=TPM_CC_Startup
984dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x00",         // param=TPM_SU_CLEAR
994dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      12);
1004dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn  std::string command_response(
1014dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x80\x01"           // tag=TPM_ST_NO_SESSIONS
1024dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x00\x00\x0A"   // size=10
1034dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x00\x00\x00",  // code=TPM_RC_SUCCESS
1044dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      10);
1056a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn  StrictMock<MockCommandTransceiver> transceiver;
10680c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn  EXPECT_CALL(transceiver, SendCommandAndWait(expected_command))
10780c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn      .WillOnce(Return(command_response));
1086a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn  StrictMock<MockAuthorizationDelegate> authorization;
1091aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn  EXPECT_CALL(authorization, GetCommandAuthorization(_, _, _, _))
11088c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi      .WillOnce(Return(true));
1116a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn  Tpm tpm(&transceiver);
1126a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn  EXPECT_EQ(TPM_RC_SUCCESS, tpm.StartupSync(TPM_SU_CLEAR, &authorization));
1136a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn}
1146a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn
1156a5f9fd320f2bd202653d09bad15a75474d49360Darren KrahnTEST(GeneratorTest, SynchronousCommandWithError) {
1166a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn  // A hand-rolled TPM2_Startup command.
1174dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn  std::string expected_command(
1184dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x80\x01"          // tag=TPM_ST_NO_SESSIONS
1194dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x00\x00\x0C"  // size=12
1204dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x00\x01\x44"  // code=TPM_CC_Startup
1214dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x00",         // param=TPM_SU_CLEAR
1224dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      12);
1234dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn  std::string command_response(
1244dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x80\x01"           // tag=TPM_ST_NO_SESSIONS
1254dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x00\x00\x0A"   // size=10
1264dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x00\x01\x01",  // code=TPM_RC_FAILURE
1274dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      10);
1286a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn  StrictMock<MockCommandTransceiver> transceiver;
12980c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn  EXPECT_CALL(transceiver, SendCommandAndWait(expected_command))
13080c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn      .WillOnce(Return(command_response));
1316a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn  StrictMock<MockAuthorizationDelegate> authorization;
1321aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn  EXPECT_CALL(authorization, GetCommandAuthorization(_, _, _, _))
13388c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi      .WillOnce(Return(true));
1346a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn  Tpm tpm(&transceiver);
1356a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn  EXPECT_EQ(TPM_RC_FAILURE, tpm.StartupSync(TPM_SU_CLEAR, &authorization));
1366a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn}
1376a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn
13888c9c242d0060034b83173054ed5a8c35078abaaUtkarsh SanghiTEST(GeneratorTest, SynchronousCommandResponseTest) {
13988c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  std::string auth_in(10, 'A');
14088c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  std::string auth_out(10, 'B');
14188c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  std::string auth_size("\x00\x00\x00\x0A", 4);
14288c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  std::string handle_in("\x40\x00\x00\x07", 4);  // primary_handle = TPM_RH_NULL
14388c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  std::string handle_out("\x80\x00\x00\x01", 4);  // out_handle
1444dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn  std::string sensitive(
1454dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x05"   // sensitive.size = 5
1464dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x01"   // sensitive.auth.size = 1
1474dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x61"       // sensitive.auth.buffer[0] = 0x65
1484dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x00",  // sensitive.data.size = 0
1494dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      7);
1504dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn  std::string public_data(
1514dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x12"  // public.size = 18
1524dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x25"  // public.type = TPM_ALG_SYMCIPHER
1534dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x0B"  // public.name_alg = SHA256
1544dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x00\x00\x00"
1554dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x00"   // public.auth_policy.size = 0
1564dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x06"   // public.sym.alg = TPM_ALG_AES
1574dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x80"   // public.sym.key_bits = 128
1584dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x43"   // public.sym.mode = TPM_ALG_CFB
1594dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x00",  // public.unique.size = 0
1604dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      20);
1614dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn  std::string outside("\x00\x00", 2);             // outside_info.size = 0
16288c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  std::string pcr_select("\x00\x00\x00\x00", 4);  // pcr_select.size = 0
16388c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi
1644dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn  std::string data(
1654dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x0F"          // creation_data.size = 15
1664dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x00\x00\x00"  // creation.pcr = 0
1674dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x00"          // creation.digest.size = 0
1684dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00"              // creation.locality = 0
1694dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x00"          // creation.parent_alg = 0
1704dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x00"          // creation.parent_name.size = 0
1714dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x00"
1724dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x00",  // creation.outside.size = 0
1734dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      17);
1744dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn  std::string hash(
1754dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x01"
1764dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x62",
1774dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      3);
1784dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn  std::string ticket(
1794dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x80\x02"          // tag = TPM_ST_SESSIONS
1804dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x40\x00\x00\x07"  // parent = TPM_RH_NULL
1814dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x00",
1824dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      8);
1834dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn  std::string name(
1844dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x03"
1854dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "KEY",
1864dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      5);
18788c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  std::string parameter_size("\x00\x00\x00\x35", 4);  // param_size = 38
18888c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi
1894dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn  std::string command_tag(
1904dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x80\x02"           // tag = TPM_ST_SESSIONS
1914dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x00\x00\x3D"   // size = 61
1924dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x00\x01\x31",  // code = TPM_CC_CreatePrimary
1934dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      10);
1944dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn  std::string response_tag(
1954dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x80\x02"           // tag = TPM_ST_SESSIONS
1964dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x00\x00\x51"   // size = 79
1974dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x00\x00\x00",  // rc = TPM_RC_SUCCESS
1984dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      10);
19988c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi
20088c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  std::string expected_command = command_tag + handle_in + auth_size + auth_in +
20188c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi                                 sensitive + public_data + outside + pcr_select;
20288c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  std::string command_response = response_tag + handle_out + parameter_size +
20388c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi                                 public_data + data + hash + ticket + name +
20488c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi                                 auth_out;
20588c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi
20688c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  StrictMock<MockCommandTransceiver> transceiver;
20780c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn  EXPECT_CALL(transceiver, SendCommandAndWait(expected_command))
20880c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn      .WillOnce(Return(command_response));
20988c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  StrictMock<MockAuthorizationDelegate> authorization;
2101aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn  EXPECT_CALL(authorization, GetCommandAuthorization(_, _, _, _))
2111aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn      .WillOnce(DoAll(SetArgPointee<3>(auth_in), Return(true)));
21288c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  EXPECT_CALL(authorization, CheckResponseAuthorization(_, auth_out))
21388c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi      .WillOnce(Return(true));
2144dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn  EXPECT_CALL(authorization, EncryptCommandParameter(_)).WillOnce(Return(true));
21588c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  EXPECT_CALL(authorization, DecryptResponseParameter(_))
21688c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi      .WillOnce(Return(true));
21788c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi
21888c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  TPM2B_SENSITIVE_CREATE in_sensitive;
21988c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  in_sensitive.size = 5;
22088c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  in_sensitive.sensitive.user_auth.size = 1;
22188c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  in_sensitive.sensitive.user_auth.buffer[0] = 'a';
22288c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  in_sensitive.sensitive.data.size = 0;
22388c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  TPM2B_PUBLIC in_public;
22488c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  in_public.size = 18;
22588c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  in_public.public_area.type = TPM_ALG_SYMCIPHER;
22688c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  in_public.public_area.name_alg = TPM_ALG_SHA256;
22788c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  in_public.public_area.object_attributes = 0;
22888c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  in_public.public_area.auth_policy.size = 0;
22988c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  in_public.public_area.parameters.sym_detail.sym.algorithm = TPM_ALG_AES;
23088c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  in_public.public_area.parameters.sym_detail.sym.key_bits.aes = 128;
23188c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  in_public.public_area.parameters.sym_detail.sym.mode.aes = TPM_ALG_CFB;
23288c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  in_public.public_area.unique.sym.size = 0;
23388c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  TPM2B_DATA outside_info;
23488c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  outside_info.size = 0;
23588c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  TPML_PCR_SELECTION create_pcr;
23688c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  create_pcr.count = 0;
23788c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi
23888c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  TPM_HANDLE key_handle;
23988c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  TPM2B_PUBLIC out_public;
24088c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  TPM2B_CREATION_DATA creation_data;
24188c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  TPM2B_DIGEST creation_hash;
24288c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  TPMT_TK_CREATION creation_ticket;
24388c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  TPM2B_NAME key_name;
24488c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi
24588c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  Tpm tpm(&transceiver);
2464dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn  TPM_RC rc = tpm.CreatePrimarySync(
2474dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      trunks::TPM_RH_NULL, "", in_sensitive, in_public, outside_info,
2484dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      create_pcr, &key_handle, &out_public, &creation_data, &creation_hash,
2494dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      &creation_ticket, &key_name, &authorization);
25088c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  ASSERT_EQ(rc, TPM_RC_SUCCESS);
25188c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  EXPECT_EQ(key_handle, 0x80000001);
25288c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  EXPECT_EQ(out_public.size, 18);
25388c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  EXPECT_EQ(creation_data.size, 15);
25488c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  EXPECT_EQ(creation_hash.size, 1);
25588c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  EXPECT_EQ(creation_hash.buffer[0], 'b');
25688c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  EXPECT_EQ(creation_ticket.tag, 0x8002);
2579caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn  EXPECT_EQ(creation_ticket.hierarchy, 0x40000007u);
25888c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  EXPECT_EQ(creation_ticket.digest.size, 0);
25988c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  EXPECT_EQ(key_name.size, 3);
26088c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  EXPECT_EQ(key_name.name[0], 'K');
26188c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  EXPECT_EQ(key_name.name[1], 'E');
26288c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi  EXPECT_EQ(key_name.name[2], 'Y');
26388c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi}
26488c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi
265a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn// A fixture for asynchronous command flow tests.
266a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahnclass CommandFlowTest : public testing::Test {
267a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn public:
268a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  CommandFlowTest() : response_code_(TPM_RC_SUCCESS) {}
269295e851b66fb19c05a14401e834337962a58c493Darren Krahn  ~CommandFlowTest() override {}
270a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn
2714dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn  void StartupCallback(TPM_RC response_code) { response_code_ = response_code; }
272a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn
273a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  void CertifyCallback(TPM_RC response_code,
2746a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn                       const TPM2B_ATTEST& certify_info,
2756a5f9fd320f2bd202653d09bad15a75474d49360Darren Krahn                       const TPMT_SIGNATURE& signature) {
276a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn    response_code_ = response_code;
277a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn    signed_data_ = StringFrom_TPM2B_ATTEST(certify_info);
2784dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn    signature_ =
2794dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn        StringFrom_TPM2B_PUBLIC_KEY_RSA(signature.signature.rsassa.sig);
280a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  }
281a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn
282a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn protected:
283a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  void Run() {
284a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn    base::RunLoop run_loop;
285a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn    run_loop.RunUntilIdle();
286a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  }
287a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn
288a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  base::MessageLoop message_loop_;
289a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  TPM_RC response_code_;
290a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  std::string signature_;
291a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  std::string signed_data_;
292a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn};
293a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn
294a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn// A functor for posting command responses. This is different than invoking the
295a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn// callback directly (e.g. via InvokeArgument) in that the original call will
296a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn// return before the response callback is invoked. This more closely matches how
297a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn// this code is expected to work when integrated.
298a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahnclass PostResponse {
299a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn public:
300a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  explicit PostResponse(const std::string& response) : response_(response) {}
3014dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn  void operator()(const base::Callback<void(const std::string&)>& callback) {
302a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn    base::MessageLoop::current()->PostTask(FROM_HERE,
303a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn                                           base::Bind(callback, response_));
304a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  }
305a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn
306a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn private:
307a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  std::string response_;
308a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn};
309a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn
310a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn// A functor to handle fake encryption / decryption of parameters.
311a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahnclass Encryptor {
312a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn public:
313a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  Encryptor(const std::string& expected_input, const std::string& output)
3144dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      : expected_input_(expected_input), output_(output) {}
3154dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn  bool operator()(std::string* value) {
316a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn    EXPECT_EQ(expected_input_, *value);
317a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn    value->assign(output_);
318a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn    return true;
319a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  }
320a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn
321a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn private:
322a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  std::string expected_input_;
323a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  std::string output_;
324a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn};
325a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn
326a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren KrahnTEST_F(CommandFlowTest, SimpleCommandFlow) {
32758a6ad9e4e634f7dbafaea963ad43076e0ed1733Darren Krahn  // A hand-rolled TPM2_Startup command.
3284dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn  std::string expected_command(
3294dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x80\x01"          // tag=TPM_ST_NO_SESSIONS
3304dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x00\x00\x0C"  // size=12
3314dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x00\x01\x44"  // code=TPM_CC_Startup
3324dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x00",         // param=TPM_SU_CLEAR
3334dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      12);
3344dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn  std::string command_response(
3354dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x80\x01"           // tag=TPM_ST_NO_SESSIONS
3364dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x00\x00\x0A"   // size=10
3374dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x00\x00\x00",  // code=TPM_RC_SUCCESS
3384dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      10);
339a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  StrictMock<MockCommandTransceiver> transceiver;
340a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  EXPECT_CALL(transceiver, SendCommand(expected_command, _))
34188c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi      .WillOnce(WithArg<1>(Invoke(PostResponse(command_response))));
342a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  StrictMock<MockAuthorizationDelegate> authorization;
3431aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn  EXPECT_CALL(authorization, GetCommandAuthorization(_, _, _, _))
34488c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi      .WillOnce(Return(true));
345a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  Tpm tpm(&transceiver);
346a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  response_code_ = TPM_RC_FAILURE;
3474dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn  tpm.Startup(
3484dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      TPM_SU_CLEAR, &authorization,
3494dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      base::Bind(&CommandFlowTest::StartupCallback, base::Unretained(this)));
350a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  Run();
351a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  EXPECT_EQ(TPM_RC_SUCCESS, response_code_);
352a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn}
353a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn
354a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren KrahnTEST_F(CommandFlowTest, SimpleCommandFlowWithError) {
355a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  // A hand-rolled TPM2_Startup command.
3564dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn  std::string expected_command(
3574dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x80\x01"          // tag=TPM_ST_NO_SESSIONS
3584dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x00\x00\x0C"  // size=12
3594dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x00\x01\x44"  // code=TPM_CC_Startup
3604dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x00",         // param=TPM_SU_CLEAR
3614dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      12);
3624dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn  std::string command_response(
3634dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x80\x01"           // tag=TPM_ST_NO_SESSIONS
3644dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x00\x00\x0A"   // size=10
3654dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x00\x01\x01",  // code=TPM_RC_FAILURE
3664dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      10);
367a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  StrictMock<MockCommandTransceiver> transceiver;
368a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  EXPECT_CALL(transceiver, SendCommand(expected_command, _))
36988c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi      .WillOnce(WithArg<1>(Invoke(PostResponse(command_response))));
370a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  StrictMock<MockAuthorizationDelegate> authorization;
3711aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn  EXPECT_CALL(authorization, GetCommandAuthorization(_, _, _, _))
37288c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi      .WillOnce(Return(true));
373a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  Tpm tpm(&transceiver);
3744dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn  tpm.Startup(
3754dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      TPM_SU_CLEAR, &authorization,
3764dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      base::Bind(&CommandFlowTest::StartupCallback, base::Unretained(this)));
377a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  Run();
378a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  EXPECT_EQ(TPM_RC_FAILURE, response_code_);
379a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn}
380a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn
381a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn// This test is designed to get good coverage of the different types of code
382a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn// generated for command / response processing. It covers:
383a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn// - input handles
384a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn// - authorization
385a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn// - multiple input and output parameters
386a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn// - parameter encryption and decryption
387a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren KrahnTEST_F(CommandFlowTest, FullCommandFlow) {
388a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  // A hand-rolled TPM2_Certify command.
389a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  std::string auth_in(10, 'A');
390a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  std::string auth_out(20, 'B');
3914dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn  std::string user_data(
3924dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x0C"
3934dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "ct_user_data",
3944dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      14);
395a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  std::string scheme("\x00\x10", 2);  // scheme=TPM_ALG_NULL
3964dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn  std::string signed_data(
3974dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x0E"
3984dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "ct_signed_data",
3994dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      16);
4004dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn  std::string signature(
4014dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x14"    // sig_scheme=RSASSA
4024dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x0B"    // hash_scheme=SHA256
4034dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x09"    // signature size
4044dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "signature",  // signature bytes
4054dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      15);
4064dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn  std::string expected_command(
4074dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x80\x02"           // tag=TPM_ST_SESSIONS
4084dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x00\x00\x30"   // size=48
4094dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x00\x01\x48"   // code=TPM_CC_Certify
4104dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x11\x22\x33\x44"   // @objectHandle
4114dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x55\x66\x77\x88"   // @signHandle
4124dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x00\x00\x0A",  // auth_size=10
4134dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      22);
414a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  expected_command += auth_in + user_data + scheme;
4154dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn  std::string command_response(
4164dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x80\x02"           // tag=TPM_ST_SESSIONS
4174dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x00\x00\x41"   // size=65
4184dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x00\x00\x00"   // code=TPM_RC_SUCCESS
4194dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      "\x00\x00\x00\x1F",  // param_size=31
4204dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      14);
421a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  command_response += signed_data + signature + auth_out;
422a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn
423a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  StrictMock<MockCommandTransceiver> transceiver;
424a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  EXPECT_CALL(transceiver, SendCommand(expected_command, _))
42588c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi      .WillOnce(WithArg<1>(Invoke(PostResponse(command_response))));
426a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  StrictMock<MockAuthorizationDelegate> authorization;
4271aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn  EXPECT_CALL(authorization, GetCommandAuthorization(_, _, _, _))
4281aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn      .WillOnce(DoAll(SetArgPointee<3>(auth_in), Return(true)));
429a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  EXPECT_CALL(authorization, CheckResponseAuthorization(_, auth_out))
43088c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi      .WillOnce(Return(true));
431a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  EXPECT_CALL(authorization, EncryptCommandParameter(_))
43288c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi      .WillOnce(Invoke(Encryptor("pt_user_data", "ct_user_data")));
433a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  EXPECT_CALL(authorization, DecryptResponseParameter(_))
43488c9c242d0060034b83173054ed5a8c35078abaaUtkarsh Sanghi      .WillOnce(Invoke(Encryptor("ct_signed_data", "pt_signed_data")));
435a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn
436a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  TPMT_SIG_SCHEME null_scheme;
437a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  null_scheme.scheme = TPM_ALG_NULL;
438a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  null_scheme.details.rsassa.hash_alg = TPM_ALG_SHA256;
439a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  Tpm tpm(&transceiver);
4404dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn  tpm.Certify(
4414dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      0x11223344u, "object_handle", 0x55667788u, "sign_handle",
4424dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      Make_TPM2B_DATA("pt_user_data"), null_scheme, &authorization,
4434dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      base::Bind(&CommandFlowTest::CertifyCallback, base::Unretained(this)));
444a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  Run();
445a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  ASSERT_EQ(TPM_RC_SUCCESS, response_code_);
446a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  EXPECT_EQ("pt_signed_data", signed_data_);
447a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn  EXPECT_EQ("signature", signature_);
448a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn}
449a4118a03f3a3e910d9e6db9c06b2d93ca85ddd0dDarren Krahn
45087496dd0090ac4f9188297e05573207db41ba2b6Darren Krahn}  // namespace trunks
451