tlcl_tests.c revision c3d488d155961d2849dfdaa4f0461df1aa95c2ca
1/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 *
5 * Tests for TPM lite library
6 */
7
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11
12#include <tss/tcs.h>
13/* Don't use the vboot constants, since they conflict with the TCS lib */
14#define VBOOT_REFERENCE_TSS_CONSTANTS_H_
15
16#include "host_common.h"
17#include "test_common.h"
18#include "tlcl.h"
19#include "tlcl_internal.h"
20#include "vboot_common.h"
21
22/* Mock data */
23static char debug_info[4096];
24static VbError_t mock_retval;
25
26/* Call to mocked VbExTpmSendReceive() */
27struct srcall
28{
29	const uint8_t *req;  /* Request */
30	uint8_t *rsp;  /* Response */
31	uint8_t rsp_buf[32];  /* Default response buffer, if not overridden */
32	int req_size;  /* Request size */
33	uint32_t req_cmd;  /* Request command code */
34	int rsp_size;  /* Response size */
35	VbError_t retval;  /* Value to return */
36};
37
38#define MAXCALLS 8
39static struct srcall calls[MAXCALLS];
40static int ncalls;
41
42/**
43 * Reset mock data (for use before each test)
44 */
45static void ResetMocks(void)
46{
47	int i;
48
49	*debug_info = 0;
50	mock_retval = VBERROR_SUCCESS;
51
52	memset(calls, 0, sizeof(calls));
53	for (i = 0; i < MAXCALLS; i++)
54		calls[i].rsp = calls[i].rsp_buf;
55	ncalls = 0;
56}
57
58/**
59 * Set response code and length for call <call_idx>.
60 */
61static void SetResponse(int call_idx, uint32_t response_code, int rsp_size)
62{
63	struct srcall *c = calls + call_idx;
64
65	c->rsp_size = rsp_size;
66	ToTpmUint32(c->rsp_buf + 6, response_code);
67}
68
69/* Mocks */
70
71VbError_t VbExTpmInit(void)
72{
73	return mock_retval;
74}
75
76
77VbError_t VbExTpmClose(void)
78{
79	return mock_retval;
80}
81
82VbError_t VbExTpmSendReceive(const uint8_t *request, uint32_t request_length,
83                             uint8_t *response, uint32_t *response_length)
84{
85	struct srcall *c = calls + ncalls++;
86
87	c->req = request;
88	c->req_size = request_length;
89
90	/* Parse out the command code */
91	FromTpmUint32(request + 6, &c->req_cmd);
92
93	// KLUDGE - remove
94	printf("TSR [%d] 0x%x\n", ncalls-1, c->req_cmd);
95
96	memset(response, 0, *response_length);
97	if (c->rsp_size)
98		memcpy(response, c->rsp, c->rsp_size);
99	*response_length = c->rsp_size;
100
101	return c->retval;
102}
103
104/**
105 * Test assorted tlcl functions
106 */
107static void TlclTest(void)
108{
109	uint8_t buf[32], buf2[32];
110
111	ResetMocks();
112	TEST_EQ(TlclLibInit(), VBERROR_SUCCESS, "Init");
113
114	ResetMocks();
115	mock_retval = VBERROR_SIMULATED;
116	TEST_EQ(TlclLibInit(), mock_retval, "Init bad");
117
118	ResetMocks();
119	TEST_EQ(TlclLibClose(), VBERROR_SUCCESS, "Close");
120
121	ResetMocks();
122	mock_retval = VBERROR_SIMULATED;
123	TEST_EQ(TlclLibClose(), mock_retval, "Close bad");
124
125	ResetMocks();
126	ToTpmUint32(buf + 2, 123);
127	TEST_EQ(TlclPacketSize(buf), 123, "TlclPacketSize");
128
129	ResetMocks();
130	ToTpmUint32(buf + 2, 10);
131	TEST_EQ(TlclSendReceive(buf, buf2, sizeof(buf2)), 0, "SendReceive");
132	TEST_PTR_EQ(calls[0].req, buf, "SendReceive req ptr");
133	TEST_EQ(calls[0].req_size, 10, "SendReceive size");
134
135	ResetMocks();
136	calls[0].retval = VBERROR_SIMULATED;
137	ToTpmUint32(buf + 2, 10);
138	TEST_EQ(TlclSendReceive(buf, buf2, sizeof(buf2)), VBERROR_SIMULATED,
139		"SendReceive fail");
140
141	ResetMocks();
142	SetResponse(0, 123, 10);
143	ToTpmUint32(buf + 2, 10);
144	TEST_EQ(TlclSendReceive(buf, buf2, sizeof(buf2)), 123,
145		"SendReceive error response");
146
147	// TODO: continue self test (if needed or doing)
148	// TODO: then retry doing self test
149
150}
151
152
153/**
154 * Test send-command functions
155 */
156static void SendCommandTest(void)
157{
158	ResetMocks();
159	TEST_EQ(TlclStartup(), 0, "SaveState");
160	TEST_EQ(calls[0].req_cmd, TPM_ORD_Startup, "  cmd");
161
162	ResetMocks();
163	TEST_EQ(TlclSaveState(), 0, "SaveState");
164	TEST_EQ(calls[0].req_cmd, TPM_ORD_SaveState, "  cmd");
165
166	ResetMocks();
167	TEST_EQ(TlclResume(), 0, "Resume");
168	TEST_EQ(calls[0].req_cmd, TPM_ORD_Startup, "  cmd");
169
170	ResetMocks();
171	TEST_EQ(TlclSelfTestFull(), 0, "SelfTestFull");
172	TEST_EQ(calls[0].req_cmd, TPM_ORD_SelfTestFull, "  cmd");
173
174	ResetMocks();
175	TEST_EQ(TlclContinueSelfTest(), 0, "ContinueSelfTest");
176	TEST_EQ(calls[0].req_cmd, TPM_ORD_ContinueSelfTest, "  cmd");
177
178	ResetMocks();
179	TEST_EQ(TlclAssertPhysicalPresence(), 0,
180		"AssertPhysicalPresence");
181	TEST_EQ(calls[0].req_cmd, TSC_ORD_PhysicalPresence, "  cmd");
182
183	ResetMocks();
184	TEST_EQ(TlclPhysicalPresenceCMDEnable(), 0,
185		"PhysicalPresenceCMDEnable");
186	TEST_EQ(calls[0].req_cmd, TSC_ORD_PhysicalPresence, "  cmd");
187
188	ResetMocks();
189	TEST_EQ(TlclFinalizePhysicalPresence(), 0,
190		"FinalizePhysicalPresence");
191	TEST_EQ(calls[0].req_cmd, TSC_ORD_PhysicalPresence, "  cmd");
192
193	ResetMocks();
194	TEST_EQ(TlclAssertPhysicalPresenceResult(), 0,
195		"AssertPhysicalPresenceResult");
196	TEST_EQ(calls[0].req_cmd, TSC_ORD_PhysicalPresence, "  cmd");
197
198	ResetMocks();
199	TEST_EQ(TlclLockPhysicalPresence(), 0,
200		"LockPhysicalPresence");
201	TEST_EQ(calls[0].req_cmd, TSC_ORD_PhysicalPresence, "  cmd");
202
203	ResetMocks();
204	TEST_EQ(TlclIsOwned(), 0, "IsOwned");
205	TEST_EQ(calls[0].req_cmd, TPM_ORD_ReadPubek, "  cmd");
206	ResetMocks();
207	calls[0].retval = VBERROR_SIMULATED;
208	TEST_NEQ(TlclIsOwned(), 0, "IsOwned");
209
210	ResetMocks();
211	TEST_EQ(TlclForceClear(), 0, "ForceClear");
212	TEST_EQ(calls[0].req_cmd, TPM_ORD_ForceClear, "  cmd");
213
214	ResetMocks();
215	TEST_EQ(TlclSetEnable(), 0, "SetEnable");
216	TEST_EQ(calls[0].req_cmd, TPM_ORD_PhysicalEnable, "  cmd");
217
218	ResetMocks();
219	TEST_EQ(TlclClearEnable(), 0, "ClearEnable");
220	TEST_EQ(calls[0].req_cmd, TPM_ORD_PhysicalDisable, "  cmd");
221
222	ResetMocks();
223	TEST_EQ(TlclSetDeactivated(0), 0, "SetDeactivated");
224	TEST_EQ(calls[0].req_cmd, TPM_ORD_PhysicalSetDeactivated, "  cmd");
225}
226
227/**
228 * NV spaces test
229 *
230 * TODO: check params/data read/written.
231 */
232static void ReadWriteTest(void)
233{
234	uint8_t buf[32];
235
236	ResetMocks();
237	TEST_EQ(TlclDefineSpace(1, 2, 3), 0, "DefineSpace");
238	TEST_EQ(calls[0].req_cmd, TPM_ORD_NV_DefineSpace, "  cmd");
239
240	ResetMocks();
241	TEST_EQ(TlclSetNvLocked(), 0, "SetNvLocked");
242	TEST_EQ(calls[0].req_cmd, TPM_ORD_NV_DefineSpace, "  cmd");
243
244	ResetMocks();
245	TEST_EQ(TlclWrite(1, buf, 3), 0, "Write");
246	TEST_EQ(calls[0].req_cmd, TPM_ORD_NV_WriteValue, "  cmd");
247
248	ResetMocks();
249	TEST_EQ(TlclRead(1, buf, 3), 0, "Read");
250	TEST_EQ(calls[0].req_cmd, TPM_ORD_NV_ReadValue, "  cmd");
251
252	ResetMocks();
253	TEST_EQ(TlclWriteLock(1), 0, "WriteLock");
254	TEST_EQ(calls[0].req_cmd, TPM_ORD_NV_WriteValue, "  cmd");
255
256	ResetMocks();
257	TEST_EQ(TlclReadLock(1), 0, "ReadLock");
258	TEST_EQ(calls[0].req_cmd, TPM_ORD_NV_ReadValue, "  cmd");
259
260	ResetMocks();
261	TEST_EQ(TlclSetGlobalLock(), 0, "SetGlobalLock");
262	TEST_EQ(calls[0].req_cmd, TPM_ORD_NV_WriteValue, "  cmd");
263}
264
265/**
266 * Test PCR funcs
267 *
268 * TODO: check params/data read/written.
269 */
270static void PcrTest(void)
271{
272	uint8_t buf[kPcrDigestLength], buf2[kPcrDigestLength];
273
274	ResetMocks();
275	TEST_EQ(TlclPCRRead(1, buf, kPcrDigestLength), 0, "PCRRead");
276	TEST_EQ(calls[0].req_cmd, TPM_ORD_PcrRead, "  cmd");
277
278	ResetMocks();
279	TEST_EQ(TlclPCRRead(1, buf, kPcrDigestLength - 1), TPM_E_IOERROR,
280		"PCRRead too small");
281
282	ResetMocks();
283	TEST_EQ(TlclExtend(1, buf, buf2), 0, "Extend");
284	TEST_EQ(calls[0].req_cmd, TPM_ORD_Extend, "  cmd");
285}
286
287/**
288 * Test flags / capabilities
289 *
290 * TODO: check params/data read/written.
291 */
292static void FlagsTest(void)
293{
294	TPM_PERMANENT_FLAGS pflags;
295	TPM_STCLEAR_FLAGS vflags;
296	uint8_t disable = 0, deactivated = 0, nvlocked = 0;
297	uint32_t u;
298	uint8_t buf[32];
299
300	ResetMocks();
301	TEST_EQ(TlclGetPermanentFlags(&pflags), 0, "GetPermanentFlags");
302	TEST_EQ(calls[0].req_cmd, TPM_ORD_GetCapability, "  cmd");
303
304	ResetMocks();
305	TEST_EQ(TlclGetSTClearFlags(&vflags), 0, "GetSTClearFlags");
306	TEST_EQ(calls[0].req_cmd, TPM_ORD_GetCapability, "  cmd");
307
308	ResetMocks();
309	TEST_EQ(TlclGetFlags(NULL, NULL, NULL), 0, "GetFlags NULL");
310	TEST_EQ(calls[0].req_cmd, TPM_ORD_GetCapability, "  cmd");
311	ResetMocks();
312	TEST_EQ(TlclGetFlags(&disable, &deactivated, &nvlocked), 0, "GetFlags");
313
314	ResetMocks();
315	TEST_EQ(TlclGetPermissions(1, &u), 0, "GetPermissions");
316	TEST_EQ(calls[0].req_cmd, TPM_ORD_GetCapability, "  cmd");
317
318	ResetMocks();
319	TEST_EQ(TlclGetOwnership(buf), 0, "GetOwnership");
320	TEST_EQ(calls[0].req_cmd, TPM_ORD_GetCapability, "  cmd");
321}
322
323/**
324 * Test random
325 *
326 * TODO: check params/data read/written.
327 * TODO: check overflow tests.
328 */
329static void RandomTest(void)
330{
331	uint8_t buf[32];
332	uint32_t size;
333
334	ResetMocks();
335	size = sizeof(buf);
336	TEST_EQ(TlclGetRandom(buf, sizeof(buf), &size), 0, "GetRandom");
337	TEST_EQ(calls[0].req_cmd, TPM_ORD_GetRandom, "  cmd");
338	TEST_EQ(size, 0, "  size 0");
339}
340
341int main(void)
342{
343	TlclTest();
344	SendCommandTest();
345	ReadWriteTest();
346	PcrTest();
347	FlagsTest();
348	RandomTest();
349
350	return gTestSuccess ? 0 : 255;
351}
352