Files
chipsec-chipsec/source/tool/chipsec/modules/common/smrr.py
T
CHIPSEC ac2ca7264f 1. We have support for uefi variables on Windows and Linux but not
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
2014-05-29 21:57:40 +01:00

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()