mirror of
https://github.com/chipsec/chipsec
synced 2026-06-08 13:31:00 +00:00
ac2ca7264f
UEFI shell. 2. Decompression of images in SPI flash parsing is only supported in Windows. 3. UEFI - Support for IA32 and i586 (Quark) 4. Added capability to use modules from an arbitrary path with the -I / --import command line option 5. Module functionality encapsulated in class inheriting BaseModule 6. Fixed loading platform specific configuration 7. Fixed issue with modules which run on multiple logical CPUs hanging on Bay Trail (Windows/Linux). The issue still exist when running from UEFI shell 8. Added template for a module - module_template.py 9. Added options to flush log files 10. Added ability to define custom platforms Driver changes: 1. Windows - Added IOCTL_ALLOC_PHYSMEM to allocate physical memory buffer 2. Linux - Fix wrpci defect
158 lines
6.9 KiB
Python
158 lines
6.9 KiB
Python
#CHIPSEC: Platform Security Assessment Framework
|
|
#Copyright (c) 2010-2014, Intel Corporation
|
|
#
|
|
#This program is free software; you can redistribute it and/or
|
|
#modify it under the terms of the GNU General Public License
|
|
#as published by the Free Software Foundation; Version 2.
|
|
#
|
|
#This program is distributed in the hope that it will be useful,
|
|
#but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
#GNU General Public License for more details.
|
|
#
|
|
#You should have received a copy of the GNU General Public License
|
|
#along with this program; if not, write to the Free Software
|
|
#Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
#
|
|
#Contact information:
|
|
#chipsec@intel.com
|
|
#
|
|
|
|
|
|
|
|
|
|
## \addtogroup modules
|
|
# __chipsec/modules/common/smrr.py__ - checks for SMRR secure configuration to protect from SMRAM cache attack
|
|
#
|
|
|
|
|
|
from chipsec.module_common import *
|
|
TAGS = [MTAG_BIOS,MTAG_SMM]
|
|
|
|
from chipsec.hal.msr import *
|
|
|
|
|
|
# ############################################################
|
|
# SPECIFY PLATFORMS THIS MODULE IS APPLICABLE TO
|
|
# ############################################################
|
|
|
|
|
|
class smrr(BaseModule):
|
|
|
|
def __init__(self):
|
|
BaseModule.__init__(self)
|
|
|
|
#
|
|
# Check that SMRR are supported by CPU in IA32_MTRRCAP_MSR[SMRR]
|
|
#
|
|
def check_SMRR_supported(self):
|
|
(eax, edx) = self.cs.msr.read_msr( 0, self.cs.Cfg.IA32_MTRRCAP_MSR )
|
|
if self.logger.VERBOSE:
|
|
self.logger.log( "[*] IA32_MTRRCAP_MSR = 0x%08X%08X" % (edx, eax) )
|
|
self.logger.log( " SMRR = %u" % ((eax&self.cs.Cfg.IA32_MTRRCAP_SMRR_MASK)>>11) )
|
|
return (eax & self.cs.Cfg.IA32_MTRRCAP_SMRR_MASK)
|
|
|
|
def check_SMRR(self):
|
|
self.logger.start_test( "CPU SMM Cache Poisoning / SMM Range Registers (SMRR)" )
|
|
if self.check_SMRR_supported():
|
|
self.logger.log_good( "OK. SMRR are supported in IA32_MTRRCAP_MSR" )
|
|
else:
|
|
self.logger.log_important( "CPU does not support SMRR protection of SMRAM" )
|
|
self.logger.log_skipped_check("CPU does not support SMRR protection of SMRAM")
|
|
return ModuleResult.SKIPPED
|
|
|
|
#
|
|
# SMRR are supported
|
|
#
|
|
smrr_ok = True
|
|
|
|
#
|
|
# 2. Check SMRR_BASE is programmed correctly (on CPU0)
|
|
#
|
|
self.logger.log( '' )
|
|
self.logger.log( "[*] Checking SMRR Base programming.." )
|
|
(eax, edx) = self.cs.msr.read_msr( 0, self.cs.Cfg.IA32_SMRR_BASE_MSR )
|
|
msr_smrrbase = ((edx << 32) | eax)
|
|
smrrbase_msr = eax
|
|
smrrbase = smrrbase_msr & self.cs.Cfg.IA32_SMRR_BASE_BASE_MASK
|
|
self.logger.log( "[*] IA32_SMRR_BASE_MSR = 0x%08X%08X" % (edx, eax) )
|
|
self.logger.log( " BASE = 0x%08X" % smrrbase )
|
|
self.logger.log( " MEMTYPE = %X" % (smrrbase_msr& self.cs.Cfg.IA32_SMRR_BASE_MEMTYPE_MASK) )
|
|
|
|
if ( 0 != smrrbase ):
|
|
if ( self.cs.Cfg.MTRR_MEMTYPE_WB == smrrbase_msr & self.cs.Cfg.IA32_SMRR_BASE_MEMTYPE_MASK ): self.logger.log_good( "SMRR Memtype is WB" )
|
|
else: self.logger.log_important( "SMRR Memtype (= %X) is not WB", (smrrbase_msr & self.cs.Cfg.IA32_SMRR_BASE_MEMTYPE_MASK) )
|
|
else:
|
|
smrr_ok = False
|
|
self.logger.log_bad( "SMRR Base is not programmed" )
|
|
|
|
if smrr_ok: self.logger.log_good( "OK so far. SMRR Base is programmed" )
|
|
|
|
#
|
|
# 3. Check SMRR_MASK is programmed and SMRR are enabled (on CPU0)
|
|
#
|
|
self.logger.log( '' )
|
|
self.logger.log( "[*] Checking SMRR Mask programming.." )
|
|
(eax, edx) = self.cs.msr.read_msr( 0, self.cs.Cfg.IA32_SMRR_MASK_MSR )
|
|
msr_smrrmask = ((edx << 32) | eax)
|
|
smrrmask_msr = eax
|
|
self.logger.log( "[*] IA32_SMRR_MASK_MSR = 0x%08X%08X" % (edx, eax) )
|
|
self.logger.log( " MASK = 0x%08X" % (smrrmask_msr & self.cs.Cfg.IA32_SMRR_MASK_MASK_MASK) )
|
|
self.logger.log( " VLD = %u" % ((smrrmask_msr & self.cs.Cfg.IA32_SMRR_MASK_VLD_MASK)>>11) )
|
|
|
|
if not ( smrrmask_msr & self.cs.Cfg.IA32_SMRR_MASK_VLD_MASK and smrrmask_msr & self.cs.Cfg.IA32_SMRR_MASK_MASK_MASK ):
|
|
smrr_ok = False
|
|
self.logger.log_bad( "SMRR are not enabled in SMRR_MASK MSR" )
|
|
|
|
if smrr_ok: self.logger.log_good( "OK so far. SMRR are enabled in SMRR_MASK MSR" )
|
|
|
|
#
|
|
# 4. Verify that SMRR_BASE/MASK MSRs have the same values on all logical CPUs
|
|
#
|
|
self.logger.log( '' )
|
|
self.logger.log( "[*] Verifying that SMRR_BASE/MASK have the same values on all logical CPUs.." )
|
|
for tid in range(self.cs.msr.get_cpu_thread_count()):
|
|
(eax, edx) = self.cs.msr.read_msr( tid, self.cs.Cfg.IA32_SMRR_BASE_MSR )
|
|
msr_base = ((edx << 32) | eax)
|
|
(eax, edx) = self.cs.msr.read_msr( tid, self.cs.Cfg.IA32_SMRR_MASK_MSR )
|
|
msr_mask = ((edx << 32) | eax)
|
|
self.logger.log( "[CPU%d] SMRR_BASE = %016X, SMRR_MASK = %016X"% (tid, msr_base, msr_mask) )
|
|
if (msr_base != msr_smrrbase) or (msr_mask != msr_smrrmask):
|
|
smrr_ok = False
|
|
self.logger.log_bad( "SMRR MSRs do not match on all CPUs" )
|
|
break
|
|
|
|
if smrr_ok: self.logger.log_good( "OK so far. SMRR MSRs match on all CPUs" )
|
|
|
|
"""
|
|
Don't want invasive action in this test
|
|
#
|
|
# 5. Reading from & writing to SMRR_BASE physical address
|
|
# writes should be dropped, reads should return all F's
|
|
#
|
|
self.logger.log( "[*] Trying to read/modify memory at SMRR_BASE address 0x%08X.." % smrrbase )
|
|
smram_buf = self.cs.mem.read_physical_mem( smrrbase, 0x10 )
|
|
#self.logger.log( "Contents at 0x%08X:\n%s" % (smrrbase, repr(smram_buf.raw)) )
|
|
self.cs.mem.write_physical_mem_dword( smrrbase, 0x90909090 )
|
|
if ( 0xFFFFFFFF == self.cs.mem.read_physical_mem_dword( smrrbase ) ):
|
|
self.logger.log_good( "OK. Memory at SMRR_BASE contains all F's and is not modifiable" )
|
|
else:
|
|
smrr_ok = False
|
|
self.logger.log_bad( "Contents of memory at SMRR_BASE are modifiable" )
|
|
"""
|
|
|
|
|
|
self.logger.log( '' )
|
|
if not smrr_ok: self.logger.log_failed_check( "SMRR protection against cache attack is not configured properly" )
|
|
else: self.logger.log_passed_check( "SMRR protection against cache attack seems properly configured" )
|
|
|
|
return smrr_ok
|
|
|
|
# --------------------------------------------------------------------------
|
|
# run( module_argv )
|
|
# Required function: run here all tests from this module
|
|
# --------------------------------------------------------------------------
|
|
def run( self, module_argv ):
|
|
return self.check_SMRR()
|
|
|