#CHIPSEC: Platform Security Assessment Framework #Copyright (c) 2010-2019, 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 # """ `Preventing & Detecting Xen Hypervisor Subversions `_ by Joanna Rutkowska & Rafal Wojtczuk Check Memory Remapping Configuration """ from chipsec.module_common import * _MODULE_NAME = 'remap' TAGS = [MTAG_SMM,MTAG_HWCONFIG] _REMAP_ADDR_MASK = 0x7FFFF00000 _TOLUD_MASK = 0xFFFFF000 class remap(BaseModule): def __init__(self): BaseModule.__init__(self) def is_supported(self): if self.cs.is_atom(): self.res = ModuleResult.NOTAPPLICABLE return False return self.cs.is_core() def check_remap_config(self): self.logger.start_test( "Memory Remapping Configuration" ) if not self.cs.is_register_defined( 'PCI0.0.0_REMAPBASE' ) or \ not self.cs.is_register_defined( 'PCI0.0.0_REMAPLIMIT' ) or \ not self.cs.is_register_defined( 'PCI0.0.0_TOUUD' ) or \ not self.cs.is_register_defined( 'PCI0.0.0_TOLUD' ) or \ not self.cs.is_register_defined( 'PCI0.0.0_TSEGMB' ): self.logger.error( "Couldn't find definition of required registers (REMAP*, TOLUD, TOUUD, TSEGMB)" ) return ModuleResult.ERROR remapbase = self.cs.read_register( 'PCI0.0.0_REMAPBASE' ) remaplimit = self.cs.read_register( 'PCI0.0.0_REMAPLIMIT' ) touud = self.cs.read_register( 'PCI0.0.0_TOUUD' ) tolud = self.cs.read_register( 'PCI0.0.0_TOLUD' ) tsegmb = self.cs.read_register( 'PCI0.0.0_TSEGMB' ) self.logger.log( "[*] Registers:" ) self.logger.log( "[*] TOUUD : 0x{:016X}".format(touud) ) self.logger.log( "[*] REMAPLIMIT: 0x{:016X}".format(remaplimit) ) self.logger.log( "[*] REMAPBASE : 0x{:016X}".format(remapbase) ) self.logger.log( "[*] TOLUD : 0x{:08X}".format(tolud) ) self.logger.log( "[*] TSEGMB : 0x{:08X}\n".format(tsegmb) ) remapbase_lock = remapbase & 0x1 remaplimit_lock = remaplimit & 0x1 touud_lock = touud & 0x1 tolud_lock = tolud & 0x1 tsegmb_lock = tsegmb & 0x1 remapbase &= _REMAP_ADDR_MASK remaplimit &= _REMAP_ADDR_MASK #remaplimit |= 0xFFFFF touud &= _REMAP_ADDR_MASK tolud &= _TOLUD_MASK tsegmb &= _TOLUD_MASK self.logger.log( "[*] Memory Map:" ) self.logger.log( "[*] Top Of Upper Memory: 0x{:016X}".format(touud) ) self.logger.log( "[*] Remap Limit Address: 0x{:016X}".format(remaplimit|0xFFFFF) ) self.logger.log( "[*] Remap Base Address : 0x{:016X}".format(remapbase) ) self.logger.log( "[*] 4GB : 0x{:016X}".format(chipsec.defines.BIT32) ) self.logger.log( "[*] Top Of Low Memory : 0x{:016X}".format(tolud) ) self.logger.log( "[*] TSEG (SMRAM) Base : 0x{:016X}\n".format(tsegmb) ) remap_ok = True self.logger.log( "[*] checking memory remap configuration.." ) if remapbase > remaplimit: self.logger.log( "[*] Memory Remap is disabled" ) else: self.logger.log( "[*] Memory Remap is enabled" ) remaplimit_addr = (remaplimit|0xFFFFF) ok = ((remaplimit_addr + 1) == touud) remap_ok = remap_ok and ok if ok: self.logger.log_good( " Remap window configuration is correct: REMAPBASE <= REMAPLIMIT < TOUUD" ) else: self.logger.log_bad( " Remap window configuration is not correct" ) ok = (0 == tolud & chipsec.defines.ALIGNED_1MB) and \ (0 == touud & chipsec.defines.ALIGNED_1MB) and \ (0 == remapbase & chipsec.defines.ALIGNED_1MB) and \ (0 == remaplimit & chipsec.defines.ALIGNED_1MB) remap_ok = remap_ok and ok if ok: self.logger.log_good( " All addresses are 1MB aligned" ) else: self.logger.log_bad( " Not all addresses are 1MB aligned" ) self.logger.log( "[*] checking if memory remap configuration is locked.." ) ok = (0 != touud_lock) remap_ok = remap_ok and ok if ok: self.logger.log_good( " TOUUD is locked" ) else: self.logger.log_bad( " TOUUD is not locked" ) ok = (0 != tolud_lock) remap_ok = remap_ok and ok if ok: self.logger.log_good( " TOLUD is locked" ) else: self.logger.log_bad( " TOLUD is not locked" ) ok = (0 != remapbase_lock) and (0 != remaplimit_lock) remap_ok = remap_ok and ok if ok: self.logger.log_good( " REMAPBASE and REMAPLIMIT are locked" ) else: self.logger.log_bad( " REMAPBASE and REMAPLIMIT are not locked" ) if remap_ok: self.res = ModuleResult.PASSED self.logger.log_passed_check( "Memory Remap is configured correctly and locked" ) else: self.res = ModuleResult.FAILED self.logger.log_failed_check( "Memory Remap is not properly configured/locked. Remaping attack may be possible" ) return self.res # -------------------------------------------------------------------------- # run( module_argv ) # Required function: run here all tests from this module # -------------------------------------------------------------------------- def run( self, module_argv ): return self.check_remap_config()