diff options
-rw-r--r-- | src/usr/devtree/bld_devtree.C | 18 | ||||
-rwxr-xr-x | src/usr/i2c/tpmdd.C | 28 | ||||
-rwxr-xr-x | src/usr/i2c/tpmdd.H | 7 | ||||
-rw-r--r-- | src/usr/secureboot/trusted/base/trustedboot_base.C | 3 | ||||
-rw-r--r-- | src/usr/secureboot/trusted/trustedboot.C | 156 | ||||
-rw-r--r-- | src/usr/secureboot/trusted/trustedboot.H | 5 |
6 files changed, 149 insertions, 68 deletions
diff --git a/src/usr/devtree/bld_devtree.C b/src/usr/devtree/bld_devtree.C index dca41c68f..5911bbaa0 100644 --- a/src/usr/devtree/bld_devtree.C +++ b/src/usr/devtree/bld_devtree.C @@ -549,8 +549,8 @@ void add_i2c_info( const TARGETING::Target* i_targ, status = "ok"; << Opal fills in phandle = <0x10000065>; << auto-filled linux,phandle = <0x10000065>; << Opal fills in - sml-get-allocated-size = <size of buffer allocated for event log> - sml-handover = <ptr to event log> + linux,sml-size = <size of buffer allocated for event log> + linux,sml-base = <ptr to event log> } */ dtOffset_t l_tpmNode = i_dt->addNode( l_busNode, @@ -581,8 +581,8 @@ void add_i2c_info( const TARGETING::Target* i_targ, // Placeholders for the tpm log which will be filled in later // We store info away so we can look up this devtree node later TRUSTEDBOOT::setTpmDevtreeInfo(*tpm, i_xscomAddr, i2cm->scomAddr); - i_dt->addPropertyCell32(l_tpmNode, "sml-get-allocated-size", 0); - i_dt->addPropertyCell64(l_tpmNode, "sml-handover", 0); + i_dt->addPropertyCell32(l_tpmNode, "linux,sml-size", 0); + i_dt->addPropertyCell64(l_tpmNode, "linux,sml-base", 0); // now remove the device we added so we don't add it again tpm = l_tpmTarget.erase(tpm); @@ -1188,7 +1188,7 @@ void add_reserved_mem(devTree * i_dt, } else { - cell_count -= sizeof(ranges[0]); + cell_count -= sizeof(ranges[0]) / sizeof(uint64_t); } } // add node style occ common node @@ -1329,10 +1329,10 @@ void load_tpmlog(devTree * i_dt, uint64_t& io_address) l_propAllocSize = reinterpret_cast<uint32_t*>( i_dt->findProperty(l_tpmNode, - "sml-get-allocated-size")); + "linux,sml-size")); l_propAddr = reinterpret_cast<uint64_t*>( i_dt->findProperty(l_tpmNode, - "sml-handover")); + "linux,sml-base")); if (NULL == l_propAllocSize || NULL == l_propAddr) @@ -1669,6 +1669,10 @@ errlHndl_t bld_fdt_reserved_mem(devTree * i_dt, uint64_t l_tpmlog_size = 0; load_tpmlog(i_dt, l_tpmlog_addr); l_tpmlog_size = l_hbrt_addr - l_tpmlog_addr; + if (0 == l_tpmlog_size) + { + l_tpmlog_addr = 0; + } #endif uint64_t l_extra_addrs[] = { l_vpd_addr, l_targ_addr, l_hbrt_addr diff --git a/src/usr/i2c/tpmdd.C b/src/usr/i2c/tpmdd.C index d2b777cb0..8c0b5319a 100755 --- a/src/usr/i2c/tpmdd.C +++ b/src/usr/i2c/tpmdd.C @@ -340,7 +340,8 @@ bool tpmPresence ( TARGETING::Target * i_target, err = tpmRead( &vendorId, vendorIdSize, - tpmInfo ); + tpmInfo, + true /* silent */ ); if ( NULL != err ) { @@ -391,7 +392,8 @@ bool tpmPresence ( TARGETING::Target * i_target, err = tpmRead( &familyId, familyIdSize, - tpmInfo ); + tpmInfo, + true /* silent */); if ( NULL != err ) { @@ -463,7 +465,8 @@ bool tpmPresence ( TARGETING::Target * i_target, // ------------------------------------------------------------------ errlHndl_t tpmRead ( void * o_buffer, size_t i_buflen, - tpm_info_t i_tpmInfo ) + tpm_info_t i_tpmInfo, + bool i_silent) { errlHndl_t err = NULL; errlHndl_t err_NACK = NULL; @@ -654,16 +657,19 @@ errlHndl_t tpmRead ( void * o_buffer, { if (err) { - // commit original NACK error with new err PLID - err_NACK->plid(err->plid()); - TRACFCOMP(g_trac_tpmdd, "tpmRead(): Committing saved NACK " - "err eid=0x%X with plid of returned err: 0x%X", - err_NACK->eid(), err_NACK->plid()); + if (!i_silent) + { + // commit original NACK error with new err PLID + err_NACK->plid(err->plid()); + TRACFCOMP(g_trac_tpmdd, "tpmRead(): Committing saved NACK " + "err eid=0x%X with plid of returned err: 0x%X", + err_NACK->eid(), err_NACK->plid()); - ERRORLOG::ErrlUserDetailsTarget(i_tpmInfo.i2cTarget) - .addToLog(err_NACK); + ERRORLOG::ErrlUserDetailsTarget(i_tpmInfo.i2cTarget) + .addToLog(err_NACK); - errlCommit(err_NACK, TPMDD_COMP_ID); + errlCommit(err_NACK, TPMDD_COMP_ID); + } } else { diff --git a/src/usr/i2c/tpmdd.H b/src/usr/i2c/tpmdd.H index ad531d67d..1daee5ab6 100755 --- a/src/usr/i2c/tpmdd.H +++ b/src/usr/i2c/tpmdd.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2015 */ +/* Contributors Listed Below - COPYRIGHT 2015,2016 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -158,12 +158,15 @@ errlHndl_t tpmPerformOp( DeviceFW::OperationType i_opType, * @param[in] i_tpmInfo Structure of I2C parameters needed to execute * the command to the I2C device driver. * + * @param[in] i_silent Don't log any error logs on failure + * * @return errlHndl_t NULL if successful, otherwise a pointer to the * error log. */ errlHndl_t tpmRead ( void * o_buffer, size_t i_buflen, - tpm_info_t i_tpmInfo ); + tpm_info_t i_tpmInfo, + bool i_silent = false); /** * @brief This function peforms the sequencing to do a write of the diff --git a/src/usr/secureboot/trusted/base/trustedboot_base.C b/src/usr/secureboot/trusted/base/trustedboot_base.C index 3f9fc9576..e782e115f 100644 --- a/src/usr/secureboot/trusted/base/trustedboot_base.C +++ b/src/usr/secureboot/trusted/base/trustedboot_base.C @@ -69,6 +69,7 @@ TpmTarget::TpmTarget() mutex_init(&tpmMutex); } + #endif @@ -82,8 +83,6 @@ errlHndl_t pcrExtend(TPM_Pcr i_pcr, #ifdef CONFIG_TPMDD MessageMode mode = MSG_MODE_ASYNC; - assert(!systemTpms.tpmDaemonShutdown, "TPM Daemon shutdown"); - TRACDCOMP( g_trac_trustedboot, ENTER_MRK"pcrExtend()" ); TRACUCOMP( g_trac_trustedboot, ENTER_MRK"pcrExtend() pcr=%d msg='%s'", i_pcr, i_logMsg); diff --git a/src/usr/secureboot/trusted/trustedboot.C b/src/usr/secureboot/trusted/trustedboot.C index 096bc1c57..06924a330 100644 --- a/src/usr/secureboot/trusted/trustedboot.C +++ b/src/usr/secureboot/trusted/trustedboot.C @@ -39,6 +39,7 @@ #include <errl/errludtarget.H> #include <errl/errludstring.H> #include <targeting/common/targetservice.H> +#include <secureboot/service.H> #include <secureboot/trustedbootif.H> #include <secureboot/trustedboot_reasoncodes.H> #include <sys/mmio.h> @@ -182,6 +183,8 @@ void* host_update_master_tpm( void *io_pArgs ) } else { + // TPM doesn't exist in the system + systemTpms.tpm[TPM_MASTER_INDEX].initAttempted = true; systemTpms.tpm[TPM_MASTER_INDEX].available = false; } @@ -209,43 +212,48 @@ void* host_update_master_tpm( void *io_pArgs ) TRACFCOMP( g_trac_trustedboot, "Master TPM Existence Fail"); - /*@ - * @errortype - * @reasoncode RC_TPM_EXISTENCE_FAIL - * @severity ERRL_SEV_UNRECOVERABLE - * @moduleid MOD_HOST_UPDATE_MASTER_TPM - * @userdata1 node - * @userdata2 0 - * @devdesc No TPMs found in system. - */ - err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE, - MOD_HOST_UPDATE_MASTER_TPM, - RC_TPM_EXISTENCE_FAIL, - TARGETING::get_huid(nodeTarget), - 0, - true /*Add HB SW Callout*/ ); + systemTpms.failedTpmsPosted = true; + if (isTpmRequired()) + { + /*@ + * @errortype + * @reasoncode RC_TPM_EXISTENCE_FAIL + * @severity ERRL_SEV_UNRECOVERABLE + * @moduleid MOD_HOST_UPDATE_MASTER_TPM + * @userdata1 node + * @userdata2 0 + * @devdesc No TPMs found in system. + */ + err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE, + MOD_HOST_UPDATE_MASTER_TPM, + RC_TPM_EXISTENCE_FAIL, + TARGETING::get_huid(nodeTarget), + 0, + true /*Add HB SW Callout*/ ); + + err->collectTrace( SECURE_COMP_NAME ); + } - err->collectTrace( SECURE_COMP_NAME ); - break; } // Lastly we will check on the backup TPM and see if it is enabled // in the attributes at least TPMDD::tpm_info_t tpmInfo; tpmInfo.chip = TPMDD::TPM_BACKUP; - err = TPMDD::tpmReadAttributes(nodeTarget, tpmInfo); - if (NULL != err) + errlHndl_t tmpErr = TPMDD::tpmReadAttributes(nodeTarget, tpmInfo); + if (NULL != tmpErr) { // We don't want to log this error we will just assume // the backup doesn't exist - delete err; - err = NULL; + delete tmpErr; + tmpErr = NULL; TRACUCOMP( g_trac_trustedboot, "host_update_master_tpm() tgt=0x%X " - "Marking backup TPM unavailable due to attribute fail", + "Marking backup TPM unavailable " + "due to attribute fail", TARGETING::get_huid(nodeTarget)); systemTpms.tpm[TPM_BACKUP_INDEX].available = false; - break; + systemTpms.tpm[TPM_BACKUP_INDEX].initAttempted = true; } else if (!tpmInfo.tpmEnabled) { @@ -254,6 +262,7 @@ void* host_update_master_tpm( void *io_pArgs ) "Marking backup TPM unavailable", TARGETING::get_huid(nodeTarget)); systemTpms.tpm[TPM_BACKUP_INDEX].available = false; + systemTpms.tpm[TPM_BACKUP_INDEX].initAttempted = true; } } while ( 0 ); @@ -275,6 +284,19 @@ void* host_update_master_tpm( void *io_pArgs ) err = tpmLogConfigEntries(systemTpms.tpm[TPM_MASTER_INDEX]); } + TRACUCOMP( g_trac_trustedboot, + EXIT_MRK"host_update_master_tpm() - " + "Master A:%d F:%d I:%d", + systemTpms.tpm[TPM_MASTER_INDEX].available, + systemTpms.tpm[TPM_MASTER_INDEX].failed, + systemTpms.tpm[TPM_MASTER_INDEX].initAttempted); + TRACUCOMP( g_trac_trustedboot, + EXIT_MRK"host_update_master_tpm() - " + "Backup A:%d F:%d I:%d", + systemTpms.tpm[TPM_BACKUP_INDEX].available, + systemTpms.tpm[TPM_BACKUP_INDEX].failed, + systemTpms.tpm[TPM_BACKUP_INDEX].initAttempted); + TRACDCOMP( g_trac_trustedboot, EXIT_MRK"host_update_master_tpm() - %s", ((NULL == err) ? "No Error" : "With Error") ); @@ -483,6 +505,27 @@ errlHndl_t tpmLogConfigEntries(TRUSTEDBOOT::TpmTarget & io_target) break; } + // TPM Required + memset(l_digest, 0, sizeof(uint64_t)); + bool l_tpmRequired = isTpmRequired(); + l_digest[0] = static_cast<uint8_t>(l_tpmRequired); + l_err = pcrExtend(PCR_1, l_digest, sizeof(l_tpmRequired), + "Tpm Required"); + if (l_err) + { + break; + } + + // HW Key Hash + sha2_hash_t l_hw_key_hash; + SECUREBOOT::getHwHashKeys(l_hw_key_hash); + l_err = pcrExtend(PCR_1, l_hw_key_hash, + sizeof(sha2_hash_t),"HW KEY HASH"); + if (l_err) + { + break; + } + } while(0); return l_err; @@ -559,7 +602,6 @@ void pcrExtendSingleTpm(TpmTarget & io_target, // Log this failure errlCommit(err, SECURE_COMP_ID); - err = NULL; } if (unlock) @@ -598,34 +640,41 @@ errlHndl_t tpmVerifyFunctionalTpmExists() } } - if (!foundFunctional) + if (!foundFunctional && !systemTpms.failedTpmsPosted) { + systemTpms.failedTpmsPosted = true; TRACFCOMP( g_trac_trustedboot, "NO FUNCTIONAL TPM FOUND"); + if (isTpmRequired()) + { + /*@ + * @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*/ ); - /*@ - * @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 ); + err->collectTrace( SECURE_COMP_NAME ); + } + else + { + TRACUCOMP( g_trac_trustedboot, + "No functional TPM's found but TPM not Required"); + } } return err; } - void* tpmDaemon(void* unused) { bool shutdownPending = false; @@ -659,6 +708,10 @@ void* tpmDaemon(void* unused) case TRUSTEDBOOT::MSG_TYPE_SHUTDOWN: { shutdownPending = true; + + // Un-register message queue from the shutdown + INITSERVICE::unregisterShutdownEvent(systemTpms.msgQ); + } break; case TRUSTEDBOOT::MSG_TYPE_PCREXTEND: @@ -746,10 +799,25 @@ void* tpmDaemon(void* unused) 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; } +bool isTpmRequired() +{ + + TARGETING::Target* pTopLevel = NULL; + (void)TARGETING::targetService().getTopLevelTarget(pTopLevel); + assert(pTopLevel != NULL, "Unable to get top level target"); + + TARGETING::ATTR_TPM_REQUIRED_type tpmRequired = + pTopLevel->getAttr<TARGETING::ATTR_TPM_REQUIRED>(); + TRACFCOMP( g_trac_trustedboot, + "Tpm Required: %s",(tpmRequired ? "Yes" : "No")); + + return tpmRequired; +} + + } // end TRUSTEDBOOT diff --git a/src/usr/secureboot/trusted/trustedboot.H b/src/usr/secureboot/trusted/trustedboot.H index ad15ff8bc..930444f77 100644 --- a/src/usr/secureboot/trusted/trustedboot.H +++ b/src/usr/secureboot/trusted/trustedboot.H @@ -61,12 +61,13 @@ class SystemTpms public: SystemTpms(): msgQ(msg_q_create()), - tpmDaemonShutdown(false) + failedTpmsPosted(false) { } + // NOTE: No destructor implemented to destroy msgQ as required for shutdown msg_q_t msgQ; ///< TrustedBootRp message queue - bool tpmDaemonShutdown; ///< Has the TPM Daemon already been shutdown + bool failedTpmsPosted; ///< Have we already posted TpmTarget tpm[MAX_SYSTEM_TPMS]; }; |