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