# CHIPSEC: Platform Security Assessment Framework # Copyright (c) 2021, 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 # """ >>> chipsec_util check list >>> chipsec_util check lock >>> chipsec_util check lock >>> chipsec_util check all Examples: >>> chipsec_util check list >>> chipsec_util check lock DebugLock >>> chipsec_util check all KEY: Lock Name - Name of Lock within configuration file State - Lock Configuration Undefined - Lock is not defined within configuration Undoc - Lock is missing configuration information Hidden - Lock is in a disabled or hidden state (unable to read the lock) Unlocked - Lock does not match value within configuration Locked - Lock matches value within configuration RW/O - Lock is identified as register is RW/O """ from argparse import ArgumentParser from chipsec.command import BaseCommand, toLoad from chipsec.hal.common.locks import LockResult from chipsec.library.defines import is_set class LOCKCHECKCommand(BaseCommand): version = "0.8" def requirements(self) -> toLoad: return toLoad.All def parse_arguments(self) -> None: parser = ArgumentParser(prog='chipsec_util check', usage=LOCKCHECKCommand.__doc__) parser_lockname = ArgumentParser(add_help=False) parser_lockname.add_argument('lockname', type=str, nargs='+', help="locknames") subparsers = parser.add_subparsers() # list parser_list = subparsers.add_parser('list') parser_list.set_defaults(func=self.list_locks) # checkall parser_checkall = subparsers.add_parser('all') parser_checkall.set_defaults(func=self.checkall_locks) # check parser_check = subparsers.add_parser('lock', parents=[parser_lockname]) parser_check.set_defaults(func=self.check_lock) parser.parse_args(self.argv, namespace=self) def log_key(self) -> None: self.logger.log(""" KEY: \tLock Name - Name of Lock within configuration file \tState - Lock Configuration \t\tUndefined - Lock is not defined within configuration \t\tUndoc - Lock is missing configuration information \t\tHidden - Lock is in a disabled or hidden state (unable to read the lock) \t\tUnlocked - Lock does not match value within configuration \t\tLocked - Lock matches value within configuration \t\tRW/O - Lock is identified as register is RW/O\n\n""") def log_header(self) -> str: ret = f'{"Lock Name":^27}|{"State":^16}|{"Consistent":^16}\n{"-" * 58}' if not self.logger.HAL: self.logger.log(ret) return f"\n\n{ret}" def list_locks(self) -> None: self.logger.log('Locks identified within the configuration:') for lock in self.cs.hals.locks.get_locks(): self.logger.log(lock) self.logger.log('') return def checkall_locks(self) -> None: locks = self.cs.hals.locks.get_locks() if not locks: self.logger.log('Did not find any locks') return if self.logger.VERBOSE: self.log_key() res = self.log_header() for lock in locks: is_locked = self.cs.hals.locks.is_locked(lock) is_locked_str = self.check_log(lock, is_locked) res = f"{res}\n{is_locked_str}" if self.logger.HAL: self.logger.log(res) return def check_lock(self) -> None: if self.logger.VERBOSE: self.log_key() res = self.log_header() for lock in self.lockname: is_locked = self.cs.hals.locks.is_locked(lock) is_locked_str = self.check_log(lock, is_locked) res = f"{res}\n{is_locked_str}" if self.logger.HAL: self.logger.log(res) return def check_log(self, lock: str, is_locked: int) -> str: consistent = "N/A" if not is_set(is_locked, LockResult.DEFINED): res_str = 'Undefined' elif not is_set(is_locked, LockResult.HAS_CONFIG): res_str = 'Undoc' elif not is_set(is_locked, LockResult.CAN_READ): res_str = 'Hidden' elif self.cs.lock.get(lock).is_access_type("RW/O"): res_str = 'RW/O' elif is_set(is_locked, LockResult.LOCKED): res_str = 'Locked' elif not is_set(is_locked, LockResult.LOCKED): res_str = 'UnLocked' else: res_str = 'Unknown' if res_str in ["RW/O", "Locked", "UnLocked"] and is_set(is_locked, LockResult.INCONSISTENT): consistent = "No" elif res_str in ["RW/O", "Locked", "UnLocked"] and not is_set(is_locked, LockResult.INCONSISTENT): consistent = "Yes" res = f'{lock[:26]:27}| {res_str:14}|{consistent:^16}' if not self.logger.HAL: self.logger.log(res) return res commands = {'check': LOCKCHECKCommand}