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