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