/* Sends a TPM command and gets a response. Returns 0 if success or the TPM * error code if error. In the firmware, waits for the self test to complete * if needed. In the host, reports the first error without retries. */ static u32 TlclSendReceive(const u8 * request, u8 * response, int max_length) { u32 result = TlclSendReceiveNoRetry(request, response, max_length); /* When compiling for the firmware, hide command failures due to the self * test not having run or completed. */ /* If the command fails because the self test has not completed, try it * again after attempting to ensure that the self test has completed. */ if (result == TPM_E_NEEDS_SELFTEST || result == TPM_E_DOING_SELFTEST) { result = TlclContinueSelfTest(); if (result != TPM_SUCCESS) { return result; } #if defined(TPM_BLOCKING_CONTINUESELFTEST) || defined(VB_RECOVERY_MODE) /* Retry only once */ result = TlclSendReceiveNoRetry(request, response, max_length); #else /* This needs serious testing. The TPM specification says: * "iii. The caller MUST wait for the actions of * TPM_ContinueSelfTest to complete before reissuing the * command C1." But, if ContinueSelfTest is non-blocking, how * do we know that the actions have completed other than trying * again? */ do { result = TlclSendReceiveNoRetry(request, response, max_length); } while (result == TPM_E_DOING_SELFTEST); #endif } return result; }
int main(int argc, char** argv) { uint32_t x; uint8_t in[20], out[20]; int time_limit_exceeded = 0; int errors = 0; TlclLibInit(); TTPM_CHECK(0, 50); TTPM_CHECK(TlclStartupIfNeeded(), 50); TTPM_CHECK(TlclContinueSelfTest(), 100); TTPM_CHECK(TlclSelfTestFull(), 1000); TTPM_CHECK(TlclAssertPhysicalPresence(), 100); TTPM_CHECK(TlclWrite(INDEX0, (uint8_t*) &x, sizeof(x)), 100); TTPM_CHECK(TlclRead(INDEX0, (uint8_t*) &x, sizeof(x)), 100); TTPM_CHECK(TlclExtend(0, in, out), 200); TTPM_CHECK(TlclSetGlobalLock(), 50); TTPM_CHECK(TlclLockPhysicalPresence(), 100); if (time_limit_exceeded || errors > 0) { printf("TEST FAILED\n"); exit(1); } else { printf("TEST SUCCEEDED\n"); return 0; } }
/* One-time call to create the WRITE_BUCKET space. */ static uint32_t RollbackTest_InitializeTPM(void) { TlclLibInit(); RETURN_ON_FAILURE(TlclStartup()); RETURN_ON_FAILURE(TlclContinueSelfTest()); RETURN_ON_FAILURE(TlclAssertPhysicalPresence()); RETURN_ON_FAILURE(SafeDefineSpace(WRITE_BUCKET_NV_INDEX, TPM_NV_PER_PPWRITE, 1)); RETURN_ON_FAILURE(RollbackTest_SetTPMState(0)); return TPM_SUCCESS; }
int main(int argc, char** argv) { uint32_t x; TlclLibInit(); TPM_CHECK(TlclStartup()); TPM_CHECK(TlclContinueSelfTest()); TPM_CHECK(TlclAssertPhysicalPresence()); TPM_CHECK(TlclWrite(INDEX0, (uint8_t*) &x, sizeof(x))); printf("TEST SUCCEEDED\n"); return 0; }
/* Sets the TPM to the right state for the next test run. * * Functionally correct ordering is tricky. Optimal ordering is even trickier * (no claim to this). May succeed only partially and require a reboot to * continue (if the TPM was deactivated at boot). */ static uint32_t RollbackTest_SetTPMState(int initialize) { uint8_t disable, deactivated; int wrong_value = 0; /* Initializes if needed */ if (initialize) { TlclLibInit(); /* Don't worry if we're already started. */ (void) TlclStartup(); RETURN_ON_FAILURE(TlclContinueSelfTest()); RETURN_ON_FAILURE(TlclAssertPhysicalPresence()); } RETURN_ON_FAILURE(RollbackTest_PartiallyAdjustFlags(&disable, &deactivated)); RETURN_ON_FAILURE(RollbackTest_AdjustIsInitialized()); RETURN_ON_FAILURE(RollbackTest_AdjustMustUseBackup()); RETURN_ON_FAILURE(RollbackTest_AdjustKernelVersions(&wrong_value)); if (RBTS.KERNEL_VERSIONS_exists) { /* Adjusting these states only makes sense when the kernel versions space * exists. */ RETURN_ON_FAILURE(RollbackTest_AdjustKernelPermissions(&wrong_value)); RETURN_ON_FAILURE(RollbackTest_AdjustKernelValue(wrong_value)); RETURN_ON_FAILURE(RollbackTest_AdjustKernelBackup()); } RETURN_ON_FAILURE(RollbackTest_AdjustDeveloperMode()); RETURN_ON_FAILURE(RollbackTest_SetOwnership(RBTS.owned)); /* Do not remove spaces between SetOwnership and AdjustWriteCount, as that * might change the ownership state. Also do not issue any writes from now * on, because AdjustWriteCount tries to avoid unneccessary clears, and after * that, any writes will obviously change the write count. */ RETURN_ON_FAILURE(RollbackTest_AdjustWriteCount()); /* Finally, disables and/or deactivates. Must deactivate before disabling */ if (!deactivated && RBTS.deactivated) { RETURN_ON_FAILURE(TlclSetDeactivated(1)); } /* It's better to do this last, even though most commands we use work with * the TPM disabled. */ if (!disable && RBTS.disable) { RETURN_ON_FAILURE(TlclClearEnable()); } return TPM_SUCCESS; }
/** * Test send-command functions */ static void SendCommandTest(void) { ResetMocks(); TEST_EQ(TlclStartup(), 0, "SaveState"); TEST_EQ(calls[0].req_cmd, TPM_ORD_Startup, " cmd"); ResetMocks(); TEST_EQ(TlclSaveState(), 0, "SaveState"); TEST_EQ(calls[0].req_cmd, TPM_ORD_SaveState, " cmd"); ResetMocks(); TEST_EQ(TlclResume(), 0, "Resume"); TEST_EQ(calls[0].req_cmd, TPM_ORD_Startup, " cmd"); ResetMocks(); TEST_EQ(TlclSelfTestFull(), 0, "SelfTestFull"); TEST_EQ(calls[0].req_cmd, TPM_ORD_SelfTestFull, " cmd"); ResetMocks(); TEST_EQ(TlclContinueSelfTest(), 0, "ContinueSelfTest"); TEST_EQ(calls[0].req_cmd, TPM_ORD_ContinueSelfTest, " cmd"); ResetMocks(); TEST_EQ(TlclAssertPhysicalPresence(), 0, "AssertPhysicalPresence"); TEST_EQ(calls[0].req_cmd, TSC_ORD_PhysicalPresence, " cmd"); ResetMocks(); TEST_EQ(TlclPhysicalPresenceCMDEnable(), 0, "PhysicalPresenceCMDEnable"); TEST_EQ(calls[0].req_cmd, TSC_ORD_PhysicalPresence, " cmd"); ResetMocks(); TEST_EQ(TlclFinalizePhysicalPresence(), 0, "FinalizePhysicalPresence"); TEST_EQ(calls[0].req_cmd, TSC_ORD_PhysicalPresence, " cmd"); ResetMocks(); TEST_EQ(TlclAssertPhysicalPresenceResult(), 0, "AssertPhysicalPresenceResult"); TEST_EQ(calls[0].req_cmd, TSC_ORD_PhysicalPresence, " cmd"); ResetMocks(); TEST_EQ(TlclLockPhysicalPresence(), 0, "LockPhysicalPresence"); TEST_EQ(calls[0].req_cmd, TSC_ORD_PhysicalPresence, " cmd"); ResetMocks(); TEST_EQ(TlclIsOwned(), 0, "IsOwned"); TEST_EQ(calls[0].req_cmd, TPM_ORD_ReadPubek, " cmd"); ResetMocks(); calls[0].retval = VBERROR_SIMULATED; TEST_NEQ(TlclIsOwned(), 0, "IsOwned"); ResetMocks(); TEST_EQ(TlclForceClear(), 0, "ForceClear"); TEST_EQ(calls[0].req_cmd, TPM_ORD_ForceClear, " cmd"); ResetMocks(); TEST_EQ(TlclSetEnable(), 0, "SetEnable"); TEST_EQ(calls[0].req_cmd, TPM_ORD_PhysicalEnable, " cmd"); ResetMocks(); TEST_EQ(TlclClearEnable(), 0, "ClearEnable"); TEST_EQ(calls[0].req_cmd, TPM_ORD_PhysicalDisable, " cmd"); ResetMocks(); TEST_EQ(TlclSetDeactivated(0), 0, "SetDeactivated"); TEST_EQ(calls[0].req_cmd, TPM_ORD_PhysicalSetDeactivated, " cmd"); }