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 */ 24static char debug_info[4096]; 25static VbError_t mock_retval; 26 27/* Call to mocked VbExTpmSendReceive() */ 28struct 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 40static struct srcall calls[MAXCALLS]; 41static int ncalls; 42 43/** 44 * Reset mock data (for use before each test) 45 */ 46static 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 */ 62static 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 72VbError_t VbExTpmInit(void) 73{ 74 return mock_retval; 75} 76 77 78VbError_t VbExTpmClose(void) 79{ 80 return mock_retval; 81} 82 83VbError_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 */ 108static 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 */ 157static 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 */ 233static 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 */ 271static 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 */ 293static 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 */ 330static 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 342int main(void) 343{ 344 TlclTest(); 345 SendCommandTest(); 346 ReadWriteTest(); 347 PcrTest(); 348 FlagsTest(); 349 RandomTest(); 350 351 return gTestSuccess ? 0 : 255; 352} 353