Files
chipsec-chipsec/source/tool/chipsec/modules/common/secureboot/keys.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

111 lines
5.3 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/secureboot/keys.py__ - verify protections of Secure Boot key EFI variables
from chipsec.module_common import *
from chipsec.file import *
from chipsec.hal.uefi import *
# ############################################################
# SPECIFY PLATFORMS THIS MODULE IS APPLICABLE TO
# ############################################################
_MODULE_NAME = 'keys'
cs.add_available_module(_MODULE_NAME, 'COMMON')
TAGS = [MTAG_SECUREBOOT]
class keys(BaseModule):
SECURE = 0x1
INSECURE = 0x2
ERROR = 0x4
def __init__(self):
BaseModule.__init__(self)
self._uefi = UEFI( self.cs.helper )
def check_EFI_variable_authentication( self, name, guid ):
self.logger.log( "[*] Checking EFI variable %s {%s}.." % (name, guid) )
orig_var = self._uefi.get_EFI_variable( name, guid, None )
if not orig_var:
self.logger.log( "[*] EFI variable %s {%s} doesn't exist" % (name, guid) )
return keys.ERROR
fname = name + '_' + guid + '.bin'
if self.logger.VERBOSE: write_file( fname, orig_var )
origvar_len = len(orig_var)
mod_var = chr( ord(orig_var[0]) ^ 0xFF ) + orig_var[1:]
if origvar_len > 1: mod_var = mod_var[:origvar_len-1] + chr( ord(mod_var[origvar_len-1]) ^ 0xFF )
if self.logger.VERBOSE: write_file( fname + '.mod', mod_var )
status = self._uefi.set_EFI_variable( name, guid, mod_var )
if not status: self.logger.log( '[*] Writing EFI variable %s did not succeed. Verifying contents..' % name )
new_var = self._uefi.get_EFI_variable( name, guid, None )
if self.logger.VERBOSE: write_file( fname + '.new', new_var )
ok = (origvar_len == len(new_var))
for i in range( origvar_len ):
if not (new_var[i] == orig_var[i]):
ok = keys.INSECURE
break
if ok == keys.INSECURE:
self.logger.log_bad( "EFI variable %s is not protected! It has been modified. Restoring original contents.." % name )
self._uefi.set_EFI_variable( name, guid, orig_var )
else:
self.logger.log_good( "Could not modify EFI variable %s {%s}" % (name, guid) )
return ok
# checks authentication of Secure Boot EFI variables
def check_secureboot_key_variables(self):
sts = 0
sts |= self.check_EFI_variable_authentication( EFI_VAR_NAME_PK, EFI_VARIABLE_DICT[EFI_VAR_NAME_PK] )
sts |= self.check_EFI_variable_authentication( EFI_VAR_NAME_KEK, EFI_VARIABLE_DICT[EFI_VAR_NAME_KEK] )
sts |= self.check_EFI_variable_authentication( EFI_VAR_NAME_db, EFI_VARIABLE_DICT[EFI_VAR_NAME_db] )
sts |= self.check_EFI_variable_authentication( EFI_VAR_NAME_dbx, EFI_VARIABLE_DICT[EFI_VAR_NAME_dbx] )
sts |= self.check_EFI_variable_authentication( EFI_VAR_NAME_SecureBoot, EFI_VARIABLE_DICT[EFI_VAR_NAME_SecureBoot] )
sts |= self.check_EFI_variable_authentication( EFI_VAR_NAME_SetupMode, EFI_VARIABLE_DICT[EFI_VAR_NAME_SetupMode] )
#sts |= self.check_EFI_variable_authentication( EFI_VAR_NAME_CustomMode, EFI_VARIABLE_DICT[EFI_VAR_NAME_CustomMode] )
if (sts & keys.ERROR) != 0: self.logger.log_important( "Some Secure Boot variables don't exist" )
ok = ((sts & keys.INSECURE) == 0)
self.logger.log('')
if ok: self.logger.log_passed_check( 'All existing Secure Boot EFI variables seem to be protected' )
else: self.logger.log_failed_check( 'One or more Secure Boot variables are not protected' )
return ok
# --------------------------------------------------------------------------
# run( module_argv )
# Required function: run here all tests from this module
# --------------------------------------------------------------------------
def run( self, module_argv ):
#self.logger.VERBOSE = True
self.logger.start_test( "Protection of Secure Boot Key and Configuraion EFI Variables" )
if not (self.cs.helper.is_win8_or_greater() or self.cs.helper.is_linux()):
self.logger.log_skipped_check( 'Currently this module can only run on Windows 8 or greater or Linux. Exiting..' )
return ModuleResult.SKIPPED
return self.check_secureboot_key_variables()