summaryrefslogtreecommitdiffstats
path: root/src/usr/secureboot/trusted/trustedboot.C
diff options
context:
space:
mode:
authorChris Engel <cjengel@us.ibm.com>2016-06-03 16:44:29 -0500
committerStephen Cprek <smcprek@us.ibm.com>2016-07-18 15:32:39 -0500
commit661c7e6a3ef2f76bfce68cb67f2f6d2d1c3d6f9b (patch)
tree33373da8433aae14fca1fb58a141cc0402d072c6 /src/usr/secureboot/trusted/trustedboot.C
parentb3f6347ef52994c4d37ac5f361b21fe4d4658462 (diff)
downloadtalos-hostboot-661c7e6a3ef2f76bfce68cb67f2f6d2d1c3d6f9b.tar.gz
talos-hostboot-661c7e6a3ef2f76bfce68cb67f2f6d2d1c3d6f9b.zip
Trustedboot PCR Extend reworked to use task message queue
Removed TPM log manager and required functions from HBB and replaced with a simple message queue Change-Id: I5f5a418b6ea8c0228229e8c45523385b488e2b6b RTC: 155519 ForwardPort: yes Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/27133 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Christopher J. Engel <cjengel@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/usr/secureboot/trusted/trustedboot.C')
-rw-r--r--src/usr/secureboot/trusted/trustedboot.C285
1 files changed, 275 insertions, 10 deletions
diff --git a/src/usr/secureboot/trusted/trustedboot.C b/src/usr/secureboot/trusted/trustedboot.C
index 936217226..096bc1c57 100644
--- a/src/usr/secureboot/trusted/trustedboot.C
+++ b/src/usr/secureboot/trusted/trustedboot.C
@@ -42,12 +42,14 @@
#include <secureboot/trustedbootif.H>
#include <secureboot/trustedboot_reasoncodes.H>
#include <sys/mmio.h>
+#include <sys/task.h>
+#include <initservice/initserviceif.H>
#include "trustedboot.H"
#include "trustedTypes.H"
#include "trustedbootCmds.H"
#include "trustedbootUtils.H"
-#include "base/tpmLogMgr.H"
-#include "base/trustedboot_base.H"
+#include "tpmLogMgr.H"
+#include "base/trustedbootMsg.H"
#include "../settings.H"
namespace TRUSTEDBOOT
@@ -197,13 +199,6 @@ void* host_update_master_tpm( void *io_pArgs )
}
}
- // Now we need to replay any existing entries in the log into the TPM
- if (!systemTpms.tpm[TPM_MASTER_INDEX].failed &&
- systemTpms.tpm[TPM_MASTER_INDEX].available)
- {
- tpmReplayLog(systemTpms.tpm[TPM_MASTER_INDEX]);
- }
-
if (systemTpms.tpm[TPM_MASTER_INDEX].failed ||
!systemTpms.tpm[TPM_MASTER_INDEX].available)
{
@@ -270,6 +265,12 @@ void* host_update_master_tpm( void *io_pArgs )
if (NULL == err)
{
+ // Start the task to start to handle the message queue/extends
+ task_create(&TRUSTEDBOOT::tpmDaemon, NULL);
+ }
+
+ if (NULL == err)
+ {
// Log config entries to TPM - needs to be after mutex_unlock
err = tpmLogConfigEntries(systemTpms.tpm[TPM_MASTER_INDEX]);
}
@@ -413,7 +414,7 @@ void tpmReplayLog(TRUSTEDBOOT::TpmTarget & io_target)
errlHndl_t tpmLogConfigEntries(TRUSTEDBOOT::TpmTarget & io_target)
{
- TRACFCOMP(g_trac_trustedboot, ENTER_MRK"tpmLogConfigEntries()");
+ TRACUCOMP(g_trac_trustedboot, ENTER_MRK"tpmLogConfigEntries()");
errlHndl_t l_err = NULL;
@@ -487,4 +488,268 @@ errlHndl_t tpmLogConfigEntries(TRUSTEDBOOT::TpmTarget & io_target)
return l_err;
}
+void pcrExtendSingleTpm(TpmTarget & io_target,
+ TPM_Pcr i_pcr,
+ TPM_Alg_Id i_algId,
+ const uint8_t* i_digest,
+ size_t i_digestSize,
+ const char* i_logMsg)
+{
+ errlHndl_t err = NULL;
+ TCG_PCR_EVENT2 eventLog;
+ bool unlock = false;
+
+ memset(&eventLog, 0, sizeof(eventLog));
+ do
+ {
+ mutex_lock( &io_target.tpmMutex );
+ unlock = true;
+
+ // Allocate the TPM log if it hasn't been already
+ if (!io_target.failed &&
+ io_target.available &&
+ NULL == io_target.logMgr)
+ {
+ io_target.logMgr = new TpmLogMgr;
+ err = TpmLogMgr_initialize(io_target.logMgr);
+ if (NULL != err)
+ {
+ break;
+ }
+ }
+
+ // Log the event, we will do this in two scenarios
+ // - !initAttempted - prior to IPL of the TPM we log for replay
+ // - initAttempted && !failed - TPM is functional so we log
+ if ((io_target.available &&
+ !io_target.initAttempted) ||
+ (io_target.available &&
+ io_target.initAttempted &&
+ !io_target.failed))
+ {
+ // Fill in TCG_PCR_EVENT2 and add to log
+ eventLog = TpmLogMgr_genLogEventPcrExtend(i_pcr, i_algId, i_digest,
+ i_digestSize, i_logMsg);
+ err = TpmLogMgr_addEvent(io_target.logMgr,&eventLog);
+ if (NULL != err)
+ {
+ break;
+ }
+ }
+
+ // If the TPM init has occurred and it is currently
+ // functional we will do our extension
+ if (io_target.available &&
+ io_target.initAttempted &&
+ !io_target.failed)
+ {
+
+ err = tpmCmdPcrExtend(&io_target,
+ i_pcr,
+ i_algId,
+ i_digest,
+ i_digestSize);
+ }
+ } while ( 0 );
+
+ if (NULL != err)
+ {
+ // We failed to extend to this TPM we can no longer use it
+ tpmMarkFailed(&io_target);
+
+ // Log this failure
+ errlCommit(err, SECURE_COMP_ID);
+ err = NULL;
+ }
+
+ if (unlock)
+ {
+ mutex_unlock(&io_target.tpmMutex);
+ }
+ return;
+}
+
+void tpmMarkFailed(TpmTarget * io_target)
+{
+
+ TRACFCOMP( g_trac_trustedboot,
+ ENTER_MRK"tpmMarkFailed() Marking TPM as failed : "
+ "tgt=0x%X chip=%d",
+ TARGETING::get_huid(io_target->nodeTarget),
+ io_target->chip);
+
+ io_target->failed = true;
+ /// @todo RTC:125287 Add fail marker to TPM log and disable TPM access
+
+}
+
+errlHndl_t tpmVerifyFunctionalTpmExists()
+{
+ errlHndl_t err = NULL;
+ bool foundFunctional = false;
+
+ for (size_t idx = 0; idx < MAX_SYSTEM_TPMS; idx ++)
+ {
+ if ((!systemTpms.tpm[idx].failed && systemTpms.tpm[idx].available) ||
+ !systemTpms.tpm[idx].initAttempted)
+ {
+ foundFunctional = true;
+ break;
+ }
+ }
+
+ if (!foundFunctional)
+ {
+ TRACFCOMP( g_trac_trustedboot,
+ "NO FUNCTIONAL TPM FOUND");
+
+ /*@
+ * @errortype
+ * @reasoncode RC_TPM_NOFUNCTIONALTPM_FAIL
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_TPM_VERIFYFUNCTIONAL
+ * @userdata1 0
+ * @userdata2 0
+ * @devdesc No functional TPMs exist in the system
+ */
+ err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MOD_TPM_VERIFYFUNCTIONAL,
+ RC_TPM_NOFUNCTIONALTPM_FAIL,
+ 0, 0,
+ true /*Add HB SW Callout*/ );
+
+ err->collectTrace( SECURE_COMP_NAME );
+
+ }
+
+ return err;
+}
+
+
+void* tpmDaemon(void* unused)
+{
+ bool shutdownPending = false;
+ errlHndl_t err = NULL;
+
+ // Mark as an independent daemon so if it crashes we terminate
+ task_detach();
+
+ TRACUCOMP( g_trac_trustedboot, ENTER_MRK "TpmDaemon Thread Start");
+
+ // Register shutdown events with init service.
+ // Done at the "end" of shutdown processing.
+ // This will flush any other messages (PCR extends) and terminate task
+ INITSERVICE::registerShutdownEvent(systemTpms.msgQ,
+ TRUSTEDBOOT::MSG_TYPE_SHUTDOWN);
+
+ Message* tb_msg = NULL;
+ while (true)
+ {
+ msg_t* msg = msg_wait(systemTpms.msgQ);
+
+ const MessageType type =
+ static_cast<MessageType>(msg->type);
+ tb_msg = NULL;
+
+ TRACUCOMP( g_trac_trustedboot, "TpmDaemon Handle CmdType %d",
+ type);
+
+ switch (type)
+ {
+ case TRUSTEDBOOT::MSG_TYPE_SHUTDOWN:
+ {
+ shutdownPending = true;
+ }
+ break;
+ case TRUSTEDBOOT::MSG_TYPE_PCREXTEND:
+ {
+ tb_msg = static_cast<TRUSTEDBOOT::Message*>(msg->extra_data);
+
+ TRUSTEDBOOT::PcrExtendMsgData* msgData =
+ reinterpret_cast<TRUSTEDBOOT::PcrExtendMsgData*>
+ (tb_msg->iv_data);
+
+ assert(tb_msg->iv_len == sizeof(TRUSTEDBOOT::PcrExtendMsgData)
+ && msgData != NULL, "Invalid PCRExtend Message");
+
+ for (size_t idx = 0;
+ idx < TRUSTEDBOOT::MAX_SYSTEM_TPMS; idx++)
+ {
+ // Add the event to this TPM,
+ // if an error occurs the TPM will
+ // be marked as failed and the error log committed
+ TRUSTEDBOOT::pcrExtendSingleTpm(
+ TRUSTEDBOOT::systemTpms.tpm[idx],
+ msgData->mPcrIndex,
+ msgData->mAlgId,
+ msgData->mDigest,
+ msgData->mDigestSize,
+ msgData->mLogMsg);
+ }
+
+ if (TRUSTEDBOOT::MSG_MODE_SYNC == tb_msg->iv_mode)
+ {
+ // Lastly make sure we are in a state
+ // where we have a functional TPM
+ // Only do for sync messages that will actually
+ // get the error log back
+ tb_msg->iv_errl =
+ TRUSTEDBOOT::tpmVerifyFunctionalTpmExists();
+ }
+ }
+ break;
+
+ default:
+ assert(false, "Invalid msg command");
+ break;
+ };
+
+ // Reply back, if we have a tb_msg do that way
+ if (NULL != tb_msg)
+ {
+ tb_msg->response(systemTpms.msgQ);
+ }
+ else
+ {
+ // use the HB message type to respond
+ int rc = msg_respond(systemTpms.msgQ, msg);
+ if (rc)
+ {
+ TRACFCOMP( g_trac_trustedboot,
+ ERR_MRK "TpmDaemon: response msg_respond failure %d",
+ rc);
+ /*@
+ * @errortype ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_TPM_TPMDAEMON
+ * @reasoncode RC_MSGRESPOND_FAIL
+ * @userdata1 rc from msq_respond()
+ * @devdesc msg_respond() failed
+ * @custdesc Firmware error during system boot
+ */
+ err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MOD_TPM_TPMDAEMON,
+ RC_MSGRESPOND_FAIL,
+ rc,
+ 0,
+ true);
+ err->collectTrace(SECURE_COMP_NAME);
+
+ // Log this failure here since we can't reply to caller
+ errlCommit(err, SECURE_COMP_ID);
+
+ }
+ }
+
+ if (shutdownPending)
+ {
+ // Exit loop and terminate task
+ break;
+ }
+ }
+ // Daemon is shutting down we can't handle any requests after this
+ systemTpms.tpmDaemonShutdown = true;
+ TRACUCOMP( g_trac_trustedboot, EXIT_MRK "TpmDaemon Thread Terminate");
+ return NULL;
+}
+
} // end TRUSTEDBOOT
OpenPOWER on IntegriCloud