mirror of
https://github.com/chipsec/chipsec
synced 2026-06-08 13:31:00 +00:00
1259e568de
Signed-off-by: Nathaniel Mitchell <nathaniel.p.mitchell@intel.com>
162 lines
5.7 KiB
Python
162 lines
5.7 KiB
Python
# 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 <lockname>
|
|
>>> chipsec_util check lock <lockname1, lockname2, ...>
|
|
>>> 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}
|