xref: /aosp_15_r20/external/gsc-utils/tpm_generated/tpm_generated_test.cc (revision 4f2df630800bdcf1d4f0decf95d8a1cb87344f5f)
1*4f2df630SAndroid Build Coastguard Worker // Copyright 2014 The ChromiumOS Authors
2*4f2df630SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*4f2df630SAndroid Build Coastguard Worker // found in the LICENSE file.
4*4f2df630SAndroid Build Coastguard Worker 
5*4f2df630SAndroid Build Coastguard Worker // Note: These tests are not generated. They test generated code.
6*4f2df630SAndroid Build Coastguard Worker 
7*4f2df630SAndroid Build Coastguard Worker #include <iterator>
8*4f2df630SAndroid Build Coastguard Worker #include <utility>
9*4f2df630SAndroid Build Coastguard Worker 
10*4f2df630SAndroid Build Coastguard Worker #include <gtest/gtest.h>
11*4f2df630SAndroid Build Coastguard Worker 
12*4f2df630SAndroid Build Coastguard Worker #include "mock_authorization_delegate.h"
13*4f2df630SAndroid Build Coastguard Worker #include "mock_command_transceiver.h"
14*4f2df630SAndroid Build Coastguard Worker #include "tpm_generated.h"
15*4f2df630SAndroid Build Coastguard Worker 
16*4f2df630SAndroid Build Coastguard Worker using testing::_;
17*4f2df630SAndroid Build Coastguard Worker using testing::DoAll;
18*4f2df630SAndroid Build Coastguard Worker using testing::Invoke;
19*4f2df630SAndroid Build Coastguard Worker using testing::Return;
20*4f2df630SAndroid Build Coastguard Worker using testing::SetArgPointee;
21*4f2df630SAndroid Build Coastguard Worker using testing::StrictMock;
22*4f2df630SAndroid Build Coastguard Worker using testing::WithArg;
23*4f2df630SAndroid Build Coastguard Worker 
24*4f2df630SAndroid Build Coastguard Worker namespace trunks {
25*4f2df630SAndroid Build Coastguard Worker 
26*4f2df630SAndroid Build Coastguard Worker // This test is designed to get good coverage of the different types of code
27*4f2df630SAndroid Build Coastguard Worker // generated for serializing and parsing structures / unions / typedefs.
TEST(GeneratorTest,SerializeParseStruct)28*4f2df630SAndroid Build Coastguard Worker TEST(GeneratorTest, SerializeParseStruct) {
29*4f2df630SAndroid Build Coastguard Worker   TPM2B_CREATION_DATA data;
30*4f2df630SAndroid Build Coastguard Worker   memset(&data, 0, sizeof(TPM2B_CREATION_DATA));
31*4f2df630SAndroid Build Coastguard Worker   data.size = sizeof(TPMS_CREATION_DATA);
32*4f2df630SAndroid Build Coastguard Worker   data.creation_data.pcr_select.count = 1;
33*4f2df630SAndroid Build Coastguard Worker   data.creation_data.pcr_select.pcr_selections[0].hash = TPM_ALG_SHA256;
34*4f2df630SAndroid Build Coastguard Worker   data.creation_data.pcr_select.pcr_selections[0].sizeof_select = 1;
35*4f2df630SAndroid Build Coastguard Worker   data.creation_data.pcr_select.pcr_selections[0].pcr_select[0] = 0;
36*4f2df630SAndroid Build Coastguard Worker   data.creation_data.pcr_digest.size = 2;
37*4f2df630SAndroid Build Coastguard Worker   data.creation_data.locality = 0;
38*4f2df630SAndroid Build Coastguard Worker   data.creation_data.parent_name_alg = TPM_ALG_SHA256;
39*4f2df630SAndroid Build Coastguard Worker   data.creation_data.parent_name.size = 3;
40*4f2df630SAndroid Build Coastguard Worker   data.creation_data.parent_qualified_name.size = 4;
41*4f2df630SAndroid Build Coastguard Worker   data.creation_data.outside_info.size = 5;
42*4f2df630SAndroid Build Coastguard Worker   std::string buffer;
43*4f2df630SAndroid Build Coastguard Worker   TPM_RC rc = Serialize_TPM2B_CREATION_DATA(data, &buffer);
44*4f2df630SAndroid Build Coastguard Worker   ASSERT_EQ(TPM_RC_SUCCESS, rc);
45*4f2df630SAndroid Build Coastguard Worker   EXPECT_EQ(35u, buffer.size());
46*4f2df630SAndroid Build Coastguard Worker   TPM2B_CREATION_DATA data2;
47*4f2df630SAndroid Build Coastguard Worker   memset(&data2, 0, sizeof(TPM2B_CREATION_DATA));
48*4f2df630SAndroid Build Coastguard Worker   std::string buffer_before = buffer;
49*4f2df630SAndroid Build Coastguard Worker   std::string buffer_parsed;
50*4f2df630SAndroid Build Coastguard Worker   rc = Parse_TPM2B_CREATION_DATA(&buffer, &data2, &buffer_parsed);
51*4f2df630SAndroid Build Coastguard Worker   ASSERT_EQ(TPM_RC_SUCCESS, rc);
52*4f2df630SAndroid Build Coastguard Worker   EXPECT_EQ(0u, buffer.size());
53*4f2df630SAndroid Build Coastguard Worker   EXPECT_EQ(buffer_before, buffer_parsed);
54*4f2df630SAndroid Build Coastguard Worker   EXPECT_EQ(data.size, data2.size);
55*4f2df630SAndroid Build Coastguard Worker   EXPECT_EQ(0, memcmp(&data.creation_data, &data2.creation_data,
56*4f2df630SAndroid Build Coastguard Worker                       sizeof(TPMS_CREATION_DATA)));
57*4f2df630SAndroid Build Coastguard Worker }
58*4f2df630SAndroid Build Coastguard Worker 
59*4f2df630SAndroid Build Coastguard Worker // This tests serializing and parsing TPM2B_ structures with zero |size|, in
60*4f2df630SAndroid Build Coastguard Worker // which case the enclosed structure isn't marshalled.
TEST(GeneratorTest,SerializeParseEmptyStruct)61*4f2df630SAndroid Build Coastguard Worker TEST(GeneratorTest, SerializeParseEmptyStruct) {
62*4f2df630SAndroid Build Coastguard Worker   TPM2B_CREATION_DATA data;
63*4f2df630SAndroid Build Coastguard Worker   memset(&data, 0, sizeof(TPM2B_CREATION_DATA));
64*4f2df630SAndroid Build Coastguard Worker   std::string buffer;
65*4f2df630SAndroid Build Coastguard Worker   TPM_RC rc = Serialize_TPM2B_CREATION_DATA(data, &buffer);
66*4f2df630SAndroid Build Coastguard Worker   ASSERT_EQ(TPM_RC_SUCCESS, rc);
67*4f2df630SAndroid Build Coastguard Worker   EXPECT_EQ(2u, buffer.size());
68*4f2df630SAndroid Build Coastguard Worker   TPM2B_CREATION_DATA data2;
69*4f2df630SAndroid Build Coastguard Worker   memset(&data2, 0, sizeof(TPM2B_CREATION_DATA));
70*4f2df630SAndroid Build Coastguard Worker   std::string buffer_before = buffer;
71*4f2df630SAndroid Build Coastguard Worker   std::string buffer_parsed;
72*4f2df630SAndroid Build Coastguard Worker   rc = Parse_TPM2B_CREATION_DATA(&buffer, &data2, &buffer_parsed);
73*4f2df630SAndroid Build Coastguard Worker   ASSERT_EQ(TPM_RC_SUCCESS, rc);
74*4f2df630SAndroid Build Coastguard Worker   EXPECT_EQ(0u, buffer.size());
75*4f2df630SAndroid Build Coastguard Worker   EXPECT_EQ(buffer_before, buffer_parsed);
76*4f2df630SAndroid Build Coastguard Worker   EXPECT_EQ(data.size, data2.size);
77*4f2df630SAndroid Build Coastguard Worker   EXPECT_EQ(0, memcmp(&data.creation_data, &data2.creation_data,
78*4f2df630SAndroid Build Coastguard Worker                       sizeof(TPMS_CREATION_DATA)));
79*4f2df630SAndroid Build Coastguard Worker }
80*4f2df630SAndroid Build Coastguard Worker 
TEST(GeneratorTest,SerializeBufferOverflow)81*4f2df630SAndroid Build Coastguard Worker TEST(GeneratorTest, SerializeBufferOverflow) {
82*4f2df630SAndroid Build Coastguard Worker   TPM2B_MAX_BUFFER value;
83*4f2df630SAndroid Build Coastguard Worker   value.size = std::size(value.buffer) + 1;
84*4f2df630SAndroid Build Coastguard Worker   std::string tmp;
85*4f2df630SAndroid Build Coastguard Worker   EXPECT_EQ(TPM_RC_INSUFFICIENT, Serialize_TPM2B_MAX_BUFFER(value, &tmp));
86*4f2df630SAndroid Build Coastguard Worker }
87*4f2df630SAndroid Build Coastguard Worker 
TEST(GeneratorTest,ParseBufferOverflow)88*4f2df630SAndroid Build Coastguard Worker TEST(GeneratorTest, ParseBufferOverflow) {
89*4f2df630SAndroid Build Coastguard Worker   TPM2B_MAX_BUFFER tmp;
90*4f2df630SAndroid Build Coastguard Worker   // Case 1: Sufficient source but overflow the destination.
91*4f2df630SAndroid Build Coastguard Worker   std::string malformed1 = "\x10\x00";
92*4f2df630SAndroid Build Coastguard Worker   malformed1 += std::string(0x1000, 'A');
93*4f2df630SAndroid Build Coastguard Worker   ASSERT_GT(0x1000u, sizeof(tmp.buffer));
94*4f2df630SAndroid Build Coastguard Worker   EXPECT_EQ(TPM_RC_INSUFFICIENT,
95*4f2df630SAndroid Build Coastguard Worker             Parse_TPM2B_MAX_BUFFER(&malformed1, &tmp, nullptr));
96*4f2df630SAndroid Build Coastguard Worker   // Case 2: Sufficient destination but overflow the source.
97*4f2df630SAndroid Build Coastguard Worker   std::string malformed2 = "\x00\x01";
98*4f2df630SAndroid Build Coastguard Worker   EXPECT_EQ(TPM_RC_INSUFFICIENT,
99*4f2df630SAndroid Build Coastguard Worker             Parse_TPM2B_MAX_BUFFER(&malformed2, &tmp, nullptr));
100*4f2df630SAndroid Build Coastguard Worker }
101*4f2df630SAndroid Build Coastguard Worker 
TEST(GeneratorTest,SynchronousCommand)102*4f2df630SAndroid Build Coastguard Worker TEST(GeneratorTest, SynchronousCommand) {
103*4f2df630SAndroid Build Coastguard Worker   // A hand-rolled TPM2_Startup command.
104*4f2df630SAndroid Build Coastguard Worker   std::string expected_command(
105*4f2df630SAndroid Build Coastguard Worker       "\x80\x01"          // tag=TPM_ST_NO_SESSIONS
106*4f2df630SAndroid Build Coastguard Worker       "\x00\x00\x00\x0C"  // size=12
107*4f2df630SAndroid Build Coastguard Worker       "\x00\x00\x01\x44"  // code=TPM_CC_Startup
108*4f2df630SAndroid Build Coastguard Worker       "\x00\x00",         // param=TPM_SU_CLEAR
109*4f2df630SAndroid Build Coastguard Worker       12);
110*4f2df630SAndroid Build Coastguard Worker   std::string command_response(
111*4f2df630SAndroid Build Coastguard Worker       "\x80\x01"           // tag=TPM_ST_NO_SESSIONS
112*4f2df630SAndroid Build Coastguard Worker       "\x00\x00\x00\x0A"   // size=10
113*4f2df630SAndroid Build Coastguard Worker       "\x00\x00\x00\x00",  // code=TPM_RC_SUCCESS
114*4f2df630SAndroid Build Coastguard Worker       10);
115*4f2df630SAndroid Build Coastguard Worker   StrictMock<MockCommandTransceiver> transceiver;
116*4f2df630SAndroid Build Coastguard Worker   EXPECT_CALL(transceiver, SendCommandAndWait(expected_command))
117*4f2df630SAndroid Build Coastguard Worker       .WillOnce(Return(command_response));
118*4f2df630SAndroid Build Coastguard Worker   StrictMock<MockAuthorizationDelegate> authorization;
119*4f2df630SAndroid Build Coastguard Worker   EXPECT_CALL(authorization, GetCommandAuthorization(_, _, _, _))
120*4f2df630SAndroid Build Coastguard Worker       .WillOnce(Return(true));
121*4f2df630SAndroid Build Coastguard Worker   Tpm tpm(&transceiver);
122*4f2df630SAndroid Build Coastguard Worker   EXPECT_EQ(TPM_RC_SUCCESS, tpm.StartupSync(TPM_SU_CLEAR, &authorization));
123*4f2df630SAndroid Build Coastguard Worker }
124*4f2df630SAndroid Build Coastguard Worker 
TEST(GeneratorTest,SynchronousCommandWithError)125*4f2df630SAndroid Build Coastguard Worker TEST(GeneratorTest, SynchronousCommandWithError) {
126*4f2df630SAndroid Build Coastguard Worker   // A hand-rolled TPM2_Startup command.
127*4f2df630SAndroid Build Coastguard Worker   std::string expected_command(
128*4f2df630SAndroid Build Coastguard Worker       "\x80\x01"          // tag=TPM_ST_NO_SESSIONS
129*4f2df630SAndroid Build Coastguard Worker       "\x00\x00\x00\x0C"  // size=12
130*4f2df630SAndroid Build Coastguard Worker       "\x00\x00\x01\x44"  // code=TPM_CC_Startup
131*4f2df630SAndroid Build Coastguard Worker       "\x00\x00",         // param=TPM_SU_CLEAR
132*4f2df630SAndroid Build Coastguard Worker       12);
133*4f2df630SAndroid Build Coastguard Worker   std::string command_response(
134*4f2df630SAndroid Build Coastguard Worker       "\x80\x01"           // tag=TPM_ST_NO_SESSIONS
135*4f2df630SAndroid Build Coastguard Worker       "\x00\x00\x00\x0A"   // size=10
136*4f2df630SAndroid Build Coastguard Worker       "\x00\x00\x01\x01",  // code=TPM_RC_FAILURE
137*4f2df630SAndroid Build Coastguard Worker       10);
138*4f2df630SAndroid Build Coastguard Worker   StrictMock<MockCommandTransceiver> transceiver;
139*4f2df630SAndroid Build Coastguard Worker   EXPECT_CALL(transceiver, SendCommandAndWait(expected_command))
140*4f2df630SAndroid Build Coastguard Worker       .WillOnce(Return(command_response));
141*4f2df630SAndroid Build Coastguard Worker   StrictMock<MockAuthorizationDelegate> authorization;
142*4f2df630SAndroid Build Coastguard Worker   EXPECT_CALL(authorization, GetCommandAuthorization(_, _, _, _))
143*4f2df630SAndroid Build Coastguard Worker       .WillOnce(Return(true));
144*4f2df630SAndroid Build Coastguard Worker   Tpm tpm(&transceiver);
145*4f2df630SAndroid Build Coastguard Worker   EXPECT_EQ(TPM_RC_FAILURE, tpm.StartupSync(TPM_SU_CLEAR, &authorization));
146*4f2df630SAndroid Build Coastguard Worker }
147*4f2df630SAndroid Build Coastguard Worker 
TEST(GeneratorTest,SynchronousCommandResponseTest)148*4f2df630SAndroid Build Coastguard Worker TEST(GeneratorTest, SynchronousCommandResponseTest) {
149*4f2df630SAndroid Build Coastguard Worker   std::string auth_in(10, 'A');
150*4f2df630SAndroid Build Coastguard Worker   std::string auth_out(10, 'B');
151*4f2df630SAndroid Build Coastguard Worker   std::string auth_size("\x00\x00\x00\x0A", 4);
152*4f2df630SAndroid Build Coastguard Worker   std::string handle_in("\x40\x00\x00\x07", 4);  // primary_handle = TPM_RH_NULL
153*4f2df630SAndroid Build Coastguard Worker   std::string handle_out("\x80\x00\x00\x01", 4);  // out_handle
154*4f2df630SAndroid Build Coastguard Worker   std::string sensitive(
155*4f2df630SAndroid Build Coastguard Worker       "\x00\x05"   // sensitive.size = 5
156*4f2df630SAndroid Build Coastguard Worker       "\x00\x01"   // sensitive.auth.size = 1
157*4f2df630SAndroid Build Coastguard Worker       "\x61"       // sensitive.auth.buffer[0] = 0x65
158*4f2df630SAndroid Build Coastguard Worker       "\x00\x00",  // sensitive.data.size = 0
159*4f2df630SAndroid Build Coastguard Worker       7);
160*4f2df630SAndroid Build Coastguard Worker   std::string public_data(
161*4f2df630SAndroid Build Coastguard Worker       "\x00\x12"  // public.size = 18
162*4f2df630SAndroid Build Coastguard Worker       "\x00\x25"  // public.type = TPM_ALG_SYMCIPHER
163*4f2df630SAndroid Build Coastguard Worker       "\x00\x0B"  // public.name_alg = SHA256
164*4f2df630SAndroid Build Coastguard Worker       "\x00\x00\x00\x00"
165*4f2df630SAndroid Build Coastguard Worker       "\x00\x00"   // public.auth_policy.size = 0
166*4f2df630SAndroid Build Coastguard Worker       "\x00\x06"   // public.sym.alg = TPM_ALG_AES
167*4f2df630SAndroid Build Coastguard Worker       "\x00\x80"   // public.sym.key_bits = 128
168*4f2df630SAndroid Build Coastguard Worker       "\x00\x43"   // public.sym.mode = TPM_ALG_CFB
169*4f2df630SAndroid Build Coastguard Worker       "\x00\x00",  // public.unique.size = 0
170*4f2df630SAndroid Build Coastguard Worker       20);
171*4f2df630SAndroid Build Coastguard Worker   std::string outside("\x00\x00", 2);             // outside_info.size = 0
172*4f2df630SAndroid Build Coastguard Worker   std::string pcr_select("\x00\x00\x00\x00", 4);  // pcr_select.size = 0
173*4f2df630SAndroid Build Coastguard Worker 
174*4f2df630SAndroid Build Coastguard Worker   std::string data(
175*4f2df630SAndroid Build Coastguard Worker       "\x00\x0F"          // creation_data.size = 15
176*4f2df630SAndroid Build Coastguard Worker       "\x00\x00\x00\x00"  // creation.pcr = 0
177*4f2df630SAndroid Build Coastguard Worker       "\x00\x00"          // creation.digest.size = 0
178*4f2df630SAndroid Build Coastguard Worker       "\x00"              // creation.locality = 0
179*4f2df630SAndroid Build Coastguard Worker       "\x00\x00"          // creation.parent_alg = 0
180*4f2df630SAndroid Build Coastguard Worker       "\x00\x00"          // creation.parent_name.size = 0
181*4f2df630SAndroid Build Coastguard Worker       "\x00\x00"
182*4f2df630SAndroid Build Coastguard Worker       "\x00\x00",  // creation.outside.size = 0
183*4f2df630SAndroid Build Coastguard Worker       17);
184*4f2df630SAndroid Build Coastguard Worker   std::string hash(
185*4f2df630SAndroid Build Coastguard Worker       "\x00\x01"
186*4f2df630SAndroid Build Coastguard Worker       "\x62",
187*4f2df630SAndroid Build Coastguard Worker       3);
188*4f2df630SAndroid Build Coastguard Worker   std::string ticket(
189*4f2df630SAndroid Build Coastguard Worker       "\x80\x02"          // tag = TPM_ST_SESSIONS
190*4f2df630SAndroid Build Coastguard Worker       "\x40\x00\x00\x07"  // parent = TPM_RH_NULL
191*4f2df630SAndroid Build Coastguard Worker       "\x00\x00",
192*4f2df630SAndroid Build Coastguard Worker       8);
193*4f2df630SAndroid Build Coastguard Worker   std::string name(
194*4f2df630SAndroid Build Coastguard Worker       "\x00\x03"
195*4f2df630SAndroid Build Coastguard Worker       "KEY",
196*4f2df630SAndroid Build Coastguard Worker       5);
197*4f2df630SAndroid Build Coastguard Worker   std::string parameter_size("\x00\x00\x00\x35", 4);  // param_size = 38
198*4f2df630SAndroid Build Coastguard Worker 
199*4f2df630SAndroid Build Coastguard Worker   std::string command_tag(
200*4f2df630SAndroid Build Coastguard Worker       "\x80\x02"           // tag = TPM_ST_SESSIONS
201*4f2df630SAndroid Build Coastguard Worker       "\x00\x00\x00\x3D"   // size = 61
202*4f2df630SAndroid Build Coastguard Worker       "\x00\x00\x01\x31",  // code = TPM_CC_CreatePrimary
203*4f2df630SAndroid Build Coastguard Worker       10);
204*4f2df630SAndroid Build Coastguard Worker   std::string response_tag(
205*4f2df630SAndroid Build Coastguard Worker       "\x80\x02"           // tag = TPM_ST_SESSIONS
206*4f2df630SAndroid Build Coastguard Worker       "\x00\x00\x00\x51"   // size = 79
207*4f2df630SAndroid Build Coastguard Worker       "\x00\x00\x00\x00",  // rc = TPM_RC_SUCCESS
208*4f2df630SAndroid Build Coastguard Worker       10);
209*4f2df630SAndroid Build Coastguard Worker 
210*4f2df630SAndroid Build Coastguard Worker   std::string expected_command = command_tag + handle_in + auth_size + auth_in +
211*4f2df630SAndroid Build Coastguard Worker                                  sensitive + public_data + outside + pcr_select;
212*4f2df630SAndroid Build Coastguard Worker   std::string command_response = response_tag + handle_out + parameter_size +
213*4f2df630SAndroid Build Coastguard Worker                                  public_data + data + hash + ticket + name +
214*4f2df630SAndroid Build Coastguard Worker                                  auth_out;
215*4f2df630SAndroid Build Coastguard Worker 
216*4f2df630SAndroid Build Coastguard Worker   StrictMock<MockCommandTransceiver> transceiver;
217*4f2df630SAndroid Build Coastguard Worker   EXPECT_CALL(transceiver, SendCommandAndWait(expected_command))
218*4f2df630SAndroid Build Coastguard Worker       .WillOnce(Return(command_response));
219*4f2df630SAndroid Build Coastguard Worker   StrictMock<MockAuthorizationDelegate> authorization;
220*4f2df630SAndroid Build Coastguard Worker   EXPECT_CALL(authorization, GetCommandAuthorization(_, _, _, _))
221*4f2df630SAndroid Build Coastguard Worker       .WillOnce(DoAll(SetArgPointee<3>(auth_in), Return(true)));
222*4f2df630SAndroid Build Coastguard Worker   EXPECT_CALL(authorization, CheckResponseAuthorization(_, auth_out))
223*4f2df630SAndroid Build Coastguard Worker       .WillOnce(Return(true));
224*4f2df630SAndroid Build Coastguard Worker   EXPECT_CALL(authorization, EncryptCommandParameter(_)).WillOnce(Return(true));
225*4f2df630SAndroid Build Coastguard Worker   EXPECT_CALL(authorization, DecryptResponseParameter(_))
226*4f2df630SAndroid Build Coastguard Worker       .WillOnce(Return(true));
227*4f2df630SAndroid Build Coastguard Worker 
228*4f2df630SAndroid Build Coastguard Worker   TPM2B_SENSITIVE_CREATE in_sensitive;
229*4f2df630SAndroid Build Coastguard Worker   in_sensitive.size = sizeof(TPMS_SENSITIVE_CREATE);
230*4f2df630SAndroid Build Coastguard Worker   in_sensitive.sensitive.user_auth.size = 1;
231*4f2df630SAndroid Build Coastguard Worker   in_sensitive.sensitive.user_auth.buffer[0] = 'a';
232*4f2df630SAndroid Build Coastguard Worker   in_sensitive.sensitive.data.size = 0;
233*4f2df630SAndroid Build Coastguard Worker   TPM2B_PUBLIC in_public;
234*4f2df630SAndroid Build Coastguard Worker   in_public.size = sizeof(TPMT_PUBLIC);
235*4f2df630SAndroid Build Coastguard Worker   in_public.public_area.type = TPM_ALG_SYMCIPHER;
236*4f2df630SAndroid Build Coastguard Worker   in_public.public_area.name_alg = TPM_ALG_SHA256;
237*4f2df630SAndroid Build Coastguard Worker   in_public.public_area.object_attributes = 0;
238*4f2df630SAndroid Build Coastguard Worker   in_public.public_area.auth_policy.size = 0;
239*4f2df630SAndroid Build Coastguard Worker   in_public.public_area.parameters.sym_detail.sym.algorithm = TPM_ALG_AES;
240*4f2df630SAndroid Build Coastguard Worker   in_public.public_area.parameters.sym_detail.sym.key_bits.aes = 128;
241*4f2df630SAndroid Build Coastguard Worker   in_public.public_area.parameters.sym_detail.sym.mode.aes = TPM_ALG_CFB;
242*4f2df630SAndroid Build Coastguard Worker   in_public.public_area.unique.sym.size = 0;
243*4f2df630SAndroid Build Coastguard Worker   TPM2B_DATA outside_info;
244*4f2df630SAndroid Build Coastguard Worker   outside_info.size = 0;
245*4f2df630SAndroid Build Coastguard Worker   TPML_PCR_SELECTION create_pcr;
246*4f2df630SAndroid Build Coastguard Worker   create_pcr.count = 0;
247*4f2df630SAndroid Build Coastguard Worker 
248*4f2df630SAndroid Build Coastguard Worker   TPM_HANDLE key_handle;
249*4f2df630SAndroid Build Coastguard Worker   TPM2B_PUBLIC out_public;
250*4f2df630SAndroid Build Coastguard Worker   TPM2B_CREATION_DATA creation_data;
251*4f2df630SAndroid Build Coastguard Worker   TPM2B_DIGEST creation_hash;
252*4f2df630SAndroid Build Coastguard Worker   TPMT_TK_CREATION creation_ticket;
253*4f2df630SAndroid Build Coastguard Worker   TPM2B_NAME key_name;
254*4f2df630SAndroid Build Coastguard Worker 
255*4f2df630SAndroid Build Coastguard Worker   Tpm tpm(&transceiver);
256*4f2df630SAndroid Build Coastguard Worker   TPM_RC rc = tpm.CreatePrimarySync(
257*4f2df630SAndroid Build Coastguard Worker       trunks::TPM_RH_NULL, "", in_sensitive, in_public, outside_info,
258*4f2df630SAndroid Build Coastguard Worker       create_pcr, &key_handle, &out_public, &creation_data, &creation_hash,
259*4f2df630SAndroid Build Coastguard Worker       &creation_ticket, &key_name, &authorization);
260*4f2df630SAndroid Build Coastguard Worker   ASSERT_EQ(rc, TPM_RC_SUCCESS);
261*4f2df630SAndroid Build Coastguard Worker   EXPECT_EQ(key_handle, 0x80000001);
262*4f2df630SAndroid Build Coastguard Worker   EXPECT_EQ(out_public.size, sizeof(TPMT_PUBLIC));
263*4f2df630SAndroid Build Coastguard Worker   EXPECT_EQ(creation_data.size, sizeof(TPMS_CREATION_DATA));
264*4f2df630SAndroid Build Coastguard Worker   EXPECT_EQ(creation_hash.size, 1);
265*4f2df630SAndroid Build Coastguard Worker   EXPECT_EQ(creation_hash.buffer[0], 'b');
266*4f2df630SAndroid Build Coastguard Worker   EXPECT_EQ(creation_ticket.tag, 0x8002);
267*4f2df630SAndroid Build Coastguard Worker   EXPECT_EQ(creation_ticket.hierarchy, 0x40000007u);
268*4f2df630SAndroid Build Coastguard Worker   EXPECT_EQ(creation_ticket.digest.size, 0);
269*4f2df630SAndroid Build Coastguard Worker   EXPECT_EQ(key_name.size, 3);
270*4f2df630SAndroid Build Coastguard Worker   EXPECT_EQ(key_name.name[0], 'K');
271*4f2df630SAndroid Build Coastguard Worker   EXPECT_EQ(key_name.name[1], 'E');
272*4f2df630SAndroid Build Coastguard Worker   EXPECT_EQ(key_name.name[2], 'Y');
273*4f2df630SAndroid Build Coastguard Worker }
274*4f2df630SAndroid Build Coastguard Worker 
275*4f2df630SAndroid Build Coastguard Worker // A fixture for asynchronous command flow tests.
276*4f2df630SAndroid Build Coastguard Worker class CommandFlowTest : public testing::Test {
277*4f2df630SAndroid Build Coastguard Worker  public:
CommandFlowTest()278*4f2df630SAndroid Build Coastguard Worker   CommandFlowTest() : response_code_(TPM_RC_SUCCESS) {}
~CommandFlowTest()279*4f2df630SAndroid Build Coastguard Worker   ~CommandFlowTest() override {}
280*4f2df630SAndroid Build Coastguard Worker 
StartupCallback(TPM_RC response_code)281*4f2df630SAndroid Build Coastguard Worker   void StartupCallback(TPM_RC response_code) { response_code_ = response_code; }
282*4f2df630SAndroid Build Coastguard Worker 
CertifyCallback(TPM_RC response_code,const TPM2B_ATTEST & certify_info,const TPMT_SIGNATURE & signature)283*4f2df630SAndroid Build Coastguard Worker   void CertifyCallback(TPM_RC response_code,
284*4f2df630SAndroid Build Coastguard Worker                        const TPM2B_ATTEST& certify_info,
285*4f2df630SAndroid Build Coastguard Worker                        const TPMT_SIGNATURE& signature) {
286*4f2df630SAndroid Build Coastguard Worker     response_code_ = response_code;
287*4f2df630SAndroid Build Coastguard Worker     signed_data_ = StringFrom_TPM2B_ATTEST(certify_info);
288*4f2df630SAndroid Build Coastguard Worker     signature_ =
289*4f2df630SAndroid Build Coastguard Worker         StringFrom_TPM2B_PUBLIC_KEY_RSA(signature.signature.rsassa.sig);
290*4f2df630SAndroid Build Coastguard Worker   }
291*4f2df630SAndroid Build Coastguard Worker 
292*4f2df630SAndroid Build Coastguard Worker  protected:
Run()293*4f2df630SAndroid Build Coastguard Worker   void Run() {}
294*4f2df630SAndroid Build Coastguard Worker 
295*4f2df630SAndroid Build Coastguard Worker   TPM_RC response_code_;
296*4f2df630SAndroid Build Coastguard Worker   std::string signature_;
297*4f2df630SAndroid Build Coastguard Worker   std::string signed_data_;
298*4f2df630SAndroid Build Coastguard Worker };
299*4f2df630SAndroid Build Coastguard Worker 
300*4f2df630SAndroid Build Coastguard Worker // A functor for posting command responses.
301*4f2df630SAndroid Build Coastguard Worker class PostResponse {
302*4f2df630SAndroid Build Coastguard Worker  public:
PostResponse(const std::string & response)303*4f2df630SAndroid Build Coastguard Worker   explicit PostResponse(const std::string& response) : response_(response) {}
operator ()(base::OnceCallback<void (const std::string &)> callback)304*4f2df630SAndroid Build Coastguard Worker   void operator()(base::OnceCallback<void(const std::string&)> callback) {
305*4f2df630SAndroid Build Coastguard Worker     std::move(callback).Run(response_);
306*4f2df630SAndroid Build Coastguard Worker   }
307*4f2df630SAndroid Build Coastguard Worker 
308*4f2df630SAndroid Build Coastguard Worker  private:
309*4f2df630SAndroid Build Coastguard Worker   std::string response_;
310*4f2df630SAndroid Build Coastguard Worker };
311*4f2df630SAndroid Build Coastguard Worker 
312*4f2df630SAndroid Build Coastguard Worker // A functor to handle fake encryption / decryption of parameters.
313*4f2df630SAndroid Build Coastguard Worker class Encryptor {
314*4f2df630SAndroid Build Coastguard Worker  public:
Encryptor(const std::string & expected_input,const std::string & output)315*4f2df630SAndroid Build Coastguard Worker   Encryptor(const std::string& expected_input, const std::string& output)
316*4f2df630SAndroid Build Coastguard Worker       : expected_input_(expected_input), output_(output) {}
operator ()(std::string * value)317*4f2df630SAndroid Build Coastguard Worker   bool operator()(std::string* value) {
318*4f2df630SAndroid Build Coastguard Worker     EXPECT_EQ(expected_input_, *value);
319*4f2df630SAndroid Build Coastguard Worker     value->assign(output_);
320*4f2df630SAndroid Build Coastguard Worker     return true;
321*4f2df630SAndroid Build Coastguard Worker   }
322*4f2df630SAndroid Build Coastguard Worker 
323*4f2df630SAndroid Build Coastguard Worker  private:
324*4f2df630SAndroid Build Coastguard Worker   std::string expected_input_;
325*4f2df630SAndroid Build Coastguard Worker   std::string output_;
326*4f2df630SAndroid Build Coastguard Worker };
327*4f2df630SAndroid Build Coastguard Worker 
TEST_F(CommandFlowTest,SimpleCommandFlow)328*4f2df630SAndroid Build Coastguard Worker TEST_F(CommandFlowTest, SimpleCommandFlow) {
329*4f2df630SAndroid Build Coastguard Worker   // A hand-rolled TPM2_Startup command.
330*4f2df630SAndroid Build Coastguard Worker   std::string expected_command(
331*4f2df630SAndroid Build Coastguard Worker       "\x80\x01"          // tag=TPM_ST_NO_SESSIONS
332*4f2df630SAndroid Build Coastguard Worker       "\x00\x00\x00\x0C"  // size=12
333*4f2df630SAndroid Build Coastguard Worker       "\x00\x00\x01\x44"  // code=TPM_CC_Startup
334*4f2df630SAndroid Build Coastguard Worker       "\x00\x00",         // param=TPM_SU_CLEAR
335*4f2df630SAndroid Build Coastguard Worker       12);
336*4f2df630SAndroid Build Coastguard Worker   std::string command_response(
337*4f2df630SAndroid Build Coastguard Worker       "\x80\x01"           // tag=TPM_ST_NO_SESSIONS
338*4f2df630SAndroid Build Coastguard Worker       "\x00\x00\x00\x0A"   // size=10
339*4f2df630SAndroid Build Coastguard Worker       "\x00\x00\x00\x00",  // code=TPM_RC_SUCCESS
340*4f2df630SAndroid Build Coastguard Worker       10);
341*4f2df630SAndroid Build Coastguard Worker   StrictMock<MockCommandTransceiver> transceiver;
342*4f2df630SAndroid Build Coastguard Worker   EXPECT_CALL(transceiver, SendCommand(expected_command, _))
343*4f2df630SAndroid Build Coastguard Worker       .WillOnce(WithArg<1>(Invoke(PostResponse(command_response))));
344*4f2df630SAndroid Build Coastguard Worker   StrictMock<MockAuthorizationDelegate> authorization;
345*4f2df630SAndroid Build Coastguard Worker   EXPECT_CALL(authorization, GetCommandAuthorization(_, _, _, _))
346*4f2df630SAndroid Build Coastguard Worker       .WillOnce(Return(true));
347*4f2df630SAndroid Build Coastguard Worker   Tpm tpm(&transceiver);
348*4f2df630SAndroid Build Coastguard Worker   response_code_ = TPM_RC_FAILURE;
349*4f2df630SAndroid Build Coastguard Worker   tpm.Startup(TPM_SU_CLEAR, &authorization,
350*4f2df630SAndroid Build Coastguard Worker               std::function<void(TPM_RC)>([this](TPM_RC response_code) {
351*4f2df630SAndroid Build Coastguard Worker                 this->StartupCallback(response_code);
352*4f2df630SAndroid Build Coastguard Worker               }));
353*4f2df630SAndroid Build Coastguard Worker   Run();
354*4f2df630SAndroid Build Coastguard Worker   EXPECT_EQ(TPM_RC_SUCCESS, response_code_);
355*4f2df630SAndroid Build Coastguard Worker }
356*4f2df630SAndroid Build Coastguard Worker 
TEST_F(CommandFlowTest,SimpleCommandFlowWithError)357*4f2df630SAndroid Build Coastguard Worker TEST_F(CommandFlowTest, SimpleCommandFlowWithError) {
358*4f2df630SAndroid Build Coastguard Worker   // A hand-rolled TPM2_Startup command.
359*4f2df630SAndroid Build Coastguard Worker   std::string expected_command(
360*4f2df630SAndroid Build Coastguard Worker       "\x80\x01"          // tag=TPM_ST_NO_SESSIONS
361*4f2df630SAndroid Build Coastguard Worker       "\x00\x00\x00\x0C"  // size=12
362*4f2df630SAndroid Build Coastguard Worker       "\x00\x00\x01\x44"  // code=TPM_CC_Startup
363*4f2df630SAndroid Build Coastguard Worker       "\x00\x00",         // param=TPM_SU_CLEAR
364*4f2df630SAndroid Build Coastguard Worker       12);
365*4f2df630SAndroid Build Coastguard Worker   std::string command_response(
366*4f2df630SAndroid Build Coastguard Worker       "\x80\x01"           // tag=TPM_ST_NO_SESSIONS
367*4f2df630SAndroid Build Coastguard Worker       "\x00\x00\x00\x0A"   // size=10
368*4f2df630SAndroid Build Coastguard Worker       "\x00\x00\x01\x01",  // code=TPM_RC_FAILURE
369*4f2df630SAndroid Build Coastguard Worker       10);
370*4f2df630SAndroid Build Coastguard Worker   StrictMock<MockCommandTransceiver> transceiver;
371*4f2df630SAndroid Build Coastguard Worker   EXPECT_CALL(transceiver, SendCommand(expected_command, _))
372*4f2df630SAndroid Build Coastguard Worker       .WillOnce(WithArg<1>(Invoke(PostResponse(command_response))));
373*4f2df630SAndroid Build Coastguard Worker   StrictMock<MockAuthorizationDelegate> authorization;
374*4f2df630SAndroid Build Coastguard Worker   EXPECT_CALL(authorization, GetCommandAuthorization(_, _, _, _))
375*4f2df630SAndroid Build Coastguard Worker       .WillOnce(Return(true));
376*4f2df630SAndroid Build Coastguard Worker   Tpm tpm(&transceiver);
377*4f2df630SAndroid Build Coastguard Worker   tpm.Startup(TPM_SU_CLEAR, &authorization,
378*4f2df630SAndroid Build Coastguard Worker               std::function<void(TPM_RC)>([this](TPM_RC response_code) {
379*4f2df630SAndroid Build Coastguard Worker                 this->StartupCallback(response_code);
380*4f2df630SAndroid Build Coastguard Worker               }));
381*4f2df630SAndroid Build Coastguard Worker   Run();
382*4f2df630SAndroid Build Coastguard Worker   EXPECT_EQ(TPM_RC_FAILURE, response_code_);
383*4f2df630SAndroid Build Coastguard Worker }
384*4f2df630SAndroid Build Coastguard Worker 
385*4f2df630SAndroid Build Coastguard Worker // This test is designed to get good coverage of the different types of code
386*4f2df630SAndroid Build Coastguard Worker // generated for command / response processing. It covers:
387*4f2df630SAndroid Build Coastguard Worker // - input handles
388*4f2df630SAndroid Build Coastguard Worker // - authorization
389*4f2df630SAndroid Build Coastguard Worker // - multiple input and output parameters
390*4f2df630SAndroid Build Coastguard Worker // - parameter encryption and decryption
TEST_F(CommandFlowTest,FullCommandFlow)391*4f2df630SAndroid Build Coastguard Worker TEST_F(CommandFlowTest, FullCommandFlow) {
392*4f2df630SAndroid Build Coastguard Worker   // A hand-rolled TPM2_Certify command.
393*4f2df630SAndroid Build Coastguard Worker   std::string auth_in(10, 'A');
394*4f2df630SAndroid Build Coastguard Worker   std::string auth_out(20, 'B');
395*4f2df630SAndroid Build Coastguard Worker   std::string user_data(
396*4f2df630SAndroid Build Coastguard Worker       "\x00\x0C"
397*4f2df630SAndroid Build Coastguard Worker       "ct_user_data",
398*4f2df630SAndroid Build Coastguard Worker       14);
399*4f2df630SAndroid Build Coastguard Worker   std::string scheme("\x00\x10", 2);  // scheme=TPM_ALG_NULL
400*4f2df630SAndroid Build Coastguard Worker   std::string signed_data(
401*4f2df630SAndroid Build Coastguard Worker       "\x00\x0E"
402*4f2df630SAndroid Build Coastguard Worker       "ct_signed_data",
403*4f2df630SAndroid Build Coastguard Worker       16);
404*4f2df630SAndroid Build Coastguard Worker   std::string signature(
405*4f2df630SAndroid Build Coastguard Worker       "\x00\x14"    // sig_scheme=RSASSA
406*4f2df630SAndroid Build Coastguard Worker       "\x00\x0B"    // hash_scheme=SHA256
407*4f2df630SAndroid Build Coastguard Worker       "\x00\x09"    // signature size
408*4f2df630SAndroid Build Coastguard Worker       "signature",  // signature bytes
409*4f2df630SAndroid Build Coastguard Worker       15);
410*4f2df630SAndroid Build Coastguard Worker   std::string expected_command(
411*4f2df630SAndroid Build Coastguard Worker       "\x80\x02"           // tag=TPM_ST_SESSIONS
412*4f2df630SAndroid Build Coastguard Worker       "\x00\x00\x00\x30"   // size=48
413*4f2df630SAndroid Build Coastguard Worker       "\x00\x00\x01\x48"   // code=TPM_CC_Certify
414*4f2df630SAndroid Build Coastguard Worker       "\x11\x22\x33\x44"   // @objectHandle
415*4f2df630SAndroid Build Coastguard Worker       "\x55\x66\x77\x88"   // @signHandle
416*4f2df630SAndroid Build Coastguard Worker       "\x00\x00\x00\x0A",  // auth_size=10
417*4f2df630SAndroid Build Coastguard Worker       22);
418*4f2df630SAndroid Build Coastguard Worker   expected_command += auth_in + user_data + scheme;
419*4f2df630SAndroid Build Coastguard Worker   std::string command_response(
420*4f2df630SAndroid Build Coastguard Worker       "\x80\x02"           // tag=TPM_ST_SESSIONS
421*4f2df630SAndroid Build Coastguard Worker       "\x00\x00\x00\x41"   // size=65
422*4f2df630SAndroid Build Coastguard Worker       "\x00\x00\x00\x00"   // code=TPM_RC_SUCCESS
423*4f2df630SAndroid Build Coastguard Worker       "\x00\x00\x00\x1F",  // param_size=31
424*4f2df630SAndroid Build Coastguard Worker       14);
425*4f2df630SAndroid Build Coastguard Worker   command_response += signed_data + signature + auth_out;
426*4f2df630SAndroid Build Coastguard Worker 
427*4f2df630SAndroid Build Coastguard Worker   StrictMock<MockCommandTransceiver> transceiver;
428*4f2df630SAndroid Build Coastguard Worker   EXPECT_CALL(transceiver, SendCommand(expected_command, _))
429*4f2df630SAndroid Build Coastguard Worker       .WillOnce(WithArg<1>(Invoke(PostResponse(command_response))));
430*4f2df630SAndroid Build Coastguard Worker   StrictMock<MockAuthorizationDelegate> authorization;
431*4f2df630SAndroid Build Coastguard Worker   EXPECT_CALL(authorization, GetCommandAuthorization(_, _, _, _))
432*4f2df630SAndroid Build Coastguard Worker       .WillOnce(DoAll(SetArgPointee<3>(auth_in), Return(true)));
433*4f2df630SAndroid Build Coastguard Worker   EXPECT_CALL(authorization, CheckResponseAuthorization(_, auth_out))
434*4f2df630SAndroid Build Coastguard Worker       .WillOnce(Return(true));
435*4f2df630SAndroid Build Coastguard Worker   EXPECT_CALL(authorization, EncryptCommandParameter(_))
436*4f2df630SAndroid Build Coastguard Worker       .WillOnce(Invoke(Encryptor("pt_user_data", "ct_user_data")));
437*4f2df630SAndroid Build Coastguard Worker   EXPECT_CALL(authorization, DecryptResponseParameter(_))
438*4f2df630SAndroid Build Coastguard Worker       .WillOnce(Invoke(Encryptor("ct_signed_data", "pt_signed_data")));
439*4f2df630SAndroid Build Coastguard Worker 
440*4f2df630SAndroid Build Coastguard Worker   TPMT_SIG_SCHEME null_scheme;
441*4f2df630SAndroid Build Coastguard Worker   null_scheme.scheme = TPM_ALG_NULL;
442*4f2df630SAndroid Build Coastguard Worker   null_scheme.details.rsassa.hash_alg = TPM_ALG_SHA256;
443*4f2df630SAndroid Build Coastguard Worker   Tpm tpm(&transceiver);
444*4f2df630SAndroid Build Coastguard Worker   tpm.Certify(
445*4f2df630SAndroid Build Coastguard Worker       0x11223344u, "object_handle", 0x55667788u, "sign_handle",
446*4f2df630SAndroid Build Coastguard Worker       Make_TPM2B_DATA("pt_user_data"), null_scheme, &authorization,
447*4f2df630SAndroid Build Coastguard Worker       std::function<void(TPM_RC, const TPM2B_ATTEST&, const TPMT_SIGNATURE&)>(
448*4f2df630SAndroid Build Coastguard Worker           [this](TPM_RC response_code, const TPM2B_ATTEST& certify_info,
449*4f2df630SAndroid Build Coastguard Worker                  const TPMT_SIGNATURE& signature) {
450*4f2df630SAndroid Build Coastguard Worker             this->CertifyCallback(response_code, certify_info, signature);
451*4f2df630SAndroid Build Coastguard Worker           }));
452*4f2df630SAndroid Build Coastguard Worker   Run();
453*4f2df630SAndroid Build Coastguard Worker   ASSERT_EQ(TPM_RC_SUCCESS, response_code_);
454*4f2df630SAndroid Build Coastguard Worker   EXPECT_EQ("pt_signed_data", signed_data_);
455*4f2df630SAndroid Build Coastguard Worker   EXPECT_EQ("signature", signature_);
456*4f2df630SAndroid Build Coastguard Worker }
457*4f2df630SAndroid Build Coastguard Worker 
458*4f2df630SAndroid Build Coastguard Worker }  // namespace trunks
459