Files
chipsec-chipsec/chipsec/modules/smm_dma.py
T

101 lines
4.9 KiB
Python

#CHIPSEC: Platform Security Assessment Framework
#Copyright (c) 2010-2015, 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
#
"""
Just like SMRAM needs to be protected from software executing on the CPU, it also needs to be protected from devices that have direct access to DRAM (DMA). Protection from DMA is configured through proper programming of SMRAM memory range. If BIOS does not correctly configure and lock the configuration, then malware could reprogram configuration and open SMRAM area to DMA access, allowing manipulation of memory that should have been protected.
DMA attacks were discussed in `Programmed I/O accesses: a threat to Virtual Machine Monitors? <http://www.ssi.gouv.fr/archive/fr/sciences/fichiers/lti/pacsec2007-duflot-papier.pdf>`_ and `System Management Mode Design and Security Issues <http://www.ssi.gouv.fr/uploads/IMG/pdf/IT_Defense_2010_final.pdf>`_. This is also discussed in `Summary of Attack against BIOS and Secure Boot` https://www.defcon.org/images/defcon-22/dc-22-presentations/Bulygin-Bazhaniul-Furtak-Loucaides/DEFCON-22-Bulygin-Bazhaniul-Furtak-Loucaides-Summary-of-attacks-against-BIOS-UPDATED.pdf
This module examines the configuration and locking of SMRAM range configuration protecting from DMA attacks. If it fails, then DMA protection may not be securely configured to protect SMRAM.
"""
from chipsec.module_common import *
_MODULE_NAME = 'smm_dma'
TAGS = [MTAG_SMM,MTAG_HWCONFIG]
_TSEG_MASK = 0xFFF00000
class smm_dma(BaseModule):
def __init__(self):
BaseModule.__init__(self)
def is_supported(self):
if self.cs.is_atom(): return False
if self.cs.is_server(): return False
else: return True
def check_tseg_locks(self):
tseg_base_lock = self.cs.get_control('TSEGBaseLock')
tseg_limit_lock = self.cs.get_control('TSEGLimitLock')
if tseg_base_lock and tseg_limit_lock:
self.logger.log_good( "TSEG range is locked" )
return ModuleResult.PASSED
else:
self.logger.log_bad( "TSEG range is not locked" )
return ModuleResult.FAILED
def check_tseg_config(self):
res = ModuleResult.FAILED
(tseg_base, tseg_limit, tseg_size ) = self.cs.cpu.get_TSEG()
self.logger.log("[*] TSEG : 0x%016X - 0x%016X (size = 0x%08X)" % (tseg_base, tseg_limit, tseg_size ))
if (self.cs.cpu.check_SMRR_supported()):
(smram_base, smram_limit, smram_size) = self.cs.cpu.get_SMRR_SMRAM()
self.logger.log("[*] SMRR range: 0x%016X - 0x%016X (size = 0x%08X)\n" % (smram_base, smram_limit, smram_size))
else:
smram_base = 0
smram_limit = 0
self.logger.log("[*] SMRR is not supported\n")
self.logger.log( "[*] checking TSEG range configuration.." )
if (0 == smram_base) and (0 == smram_limit):
res = ModuleResult.WARNING
self.logger.log_warn_check( "TSEG is properly configured but can't determine if it covers entire SMRAM" )
else:
if (tseg_base <= smram_base) and (smram_limit <= tseg_limit):
#if (tseg_base == smram_base) and (tseg_size == smram_size):
self.logger.log_good( "TSEG range covers entire SMRAM" )
if self.check_tseg_locks() == ModuleResult.PASSED:
res = ModuleResult.PASSED
self.logger.log_passed_check( "TSEG is properly configured. SMRAM is protected from DMA attacks" )
else:
self.logger.log_failed_check( "TSEG is properly configured, but the configuration is not locked." )
else:
self.logger.log_bad( "TSEG range doesn't cover entire SMRAM" )
self.logger.log_failed_check( "TSEG is not properly configured. Portions of SMRAM may be vulnerable to DMA attacks" )
return res
# --------------------------------------------------------------------------
# run( module_argv )
# Required function: run here all tests from this module
# --------------------------------------------------------------------------
def run( self, module_argv ):
self.logger.start_test( "SMM TSEG Range Configuration Check" )
self.res = self.check_tseg_config()
return self.res