-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2023, 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
-
-importcopy
-fromchipsec.parsersimportBaseConfigParser
-fromchipsec.parsersimportStage
-fromchipsec.parsersimportinfo_data
-
-CONFIG_TAG='configuration'
-
-
-def_get_range_data(xml_node,attr):
- int_items=[]
- foriteminxml_node.attrib[attr].split(','):
- item=item.strip()
- ifitem.upper().endswith('*'):
- x=int(item.replace('*','0'),0)
- int_items.extend(range(x,x+0x10))
- elif'-'initem:
- item_min,item_max=item.split('-',1)
- int_items.extend(range(int(item_min,0),int(item_max,0)+1))
- else:
- int_items.append(int(item,0))
- returnint_items
-
-
-def_config_convert_data(xml_node,did_is_range=False):
- INT_KEYS=['dev','fun','vid','did','rid','offset',
- 'bit','size','port','msr','value','address',
- 'fixed_address','base_align','align_bits','mask',
- 'reg_align','limit_align','regh_align',
- 'width','reg']
- BOOL_KEYS=['req_pch']
- INT_LIST_KEYS=['bus']
- STR_LIST_KEYS=['config']
- RANGE_LIST_KEYS=['detection_value']
- ifdid_is_range:
- INT_KEYS.remove('did')
- RANGE_LIST_KEYS.append('did')
- node_data={}
- forkeyinxml_node.attrib:
- ifkeyinINT_KEYS:
- node_data[key]=int(xml_node.attrib[key],0)
- elifkeyinINT_LIST_KEYS:
- node_data[key]=[int(xml_node.attrib[key],0)]
- elifkeyinSTR_LIST_KEYS:
- node_data[key]=[x.strip()forxinxml_node.attrib[key].split(',')]
- elifkeyinRANGE_LIST_KEYS:
- node_data[key]=_get_range_data(xml_node,key)
- elifkeyinBOOL_KEYS:
- node_data[key]=xml_node.attrib[key].lower()=='true'
- else:
- node_data[key]=xml_node.attrib[key]
- returnnode_data
-
-
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2023, 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
-#
-
-fromfnmatchimportfnmatch
-importimportlib
-importos
-importxml.etree.ElementTreeasET
-fromchipsec.definesimportis_hex
-fromchipsec.exceptionsimportCSConfigError
-fromchipsec.fileimportget_main_dir
-fromchipsec.loggerimportlogger
-fromchipsec.parsersimportStage
-fromchipsec.parsersimportstage_info,config_data
-
-LOAD_COMMON=True
-
-CHIPSET_ID_UNKNOWN=0
-
-CHIPSET_CODE_UNKNOWN=''
-
-PROC_FAMILY={}
-
-PCH_CODE_PREFIX='PCH_'
-
-
-
[docs]classbase_primitive:
- '''
- The primitive base class implements common functionality shared across most primitives.
- '''
-
- def__init__(self):
- self.fuzz_complete=False# this flag is raised when the mutations are exhausted.
- self.fuzz_library=[]# library of static fuzz heuristics to cycle through.
- self.fuzzable=True# flag controlling whether or not the given primitive is to be fuzzed.
- self.mutant_index=0# current mutation index into the fuzz library.
- self.original_value=None# original value of primitive.
- self.rendered=""# rendered value of primitive.
- self.value=None# current value of primitive.
-
-
[docs]defexhaust(self):
- '''
- Exhaust the possible mutations for this primitive.
-
- @rtype: Integer
- @return: The number of mutations to reach exhaustion
- '''
-
- num=self.num_mutations()-self.mutant_index
-
- self.fuzz_complete=True
- self.mutant_index=self.num_mutations()
- self.value=self.original_value
-
- returnnum
-
-
[docs]defmutate(self):
- '''
- Mutate the primitive by stepping through the fuzz library, return False on completion.
-
- @rtype: Boolean
- @return: True on success, False otherwise.
- '''
-
- # if we've ran out of mutations, raise the completion flag.
- ifself.mutant_index==self.num_mutations():
- self.fuzz_complete=True
-
- # if fuzzing was disabled or complete, and mutate() is called, ensure the original value is restored.
- ifnotself.fuzzableorself.fuzz_complete:
- self.value=self.original_value
- returnFalse
-
- # update the current value from the fuzz library.
- self.value=self.fuzz_library[self.mutant_index]
-
- # increment the mutation count.
- self.mutant_index+=1
-
- returnTrue
-
-
[docs]defnum_mutations(self):
- '''
- Calculate and return the total number of mutations for this individual primitive.
-
- @rtype: Integer
- @return: Number of mutated forms this primitive can take
- '''
-
- returnlen(self.fuzz_library)
-
-
[docs]defrender(self):
- '''
- Nothing fancy on render, simply return the value.
- '''
-
- self.rendered=self.value
- returnself.rendered
-
-
[docs]defreset(self):
- '''
- Reset this primitive to the starting mutation state.
- '''
-
- self.fuzz_complete=False
- self.mutant_index=0
- self.value=self.original_value
[docs]classgroup(base_primitive):
- def__init__(self,name,values):
- '''
- This primitive represents a list of static values, stepping through each one on mutation. You can tie a block
- to a group primitive to specify that the block should cycle through all possible mutations for *each* value
- within the group. The group primitive is useful for example for representing a list of valid opcodes.
-
- @type name: String
- @param name: Name of group
- @type values: List or raw data
- @param values: List of possible raw values this group can take.
- '''
- super(group,self).__init__()
- self.name=name
- self.values=values
- self.fuzzable=True
-
- self.s_type="group"
- self.value=self.values[0]
- self.original_value=self.values[0]
-
- # sanity check that values list only contains strings (or raw data)
- ifself.values!=[]:
- forvalinself.values:
- assertisinstance(val,str),"Value list may only contain strings or raw data"
-
-
[docs]defmutate(self):
- '''
- Move to the next item in the values list.
-
- @rtype: False
- @return: False
- '''
-
- ifself.mutant_index==self.num_mutations():
- self.fuzz_complete=True
-
- # if fuzzing was disabled or complete, and mutate() is called, ensure the original value is restored.
- ifnotself.fuzzableorself.fuzz_complete:
- self.value=self.values[0]
- returnFalse
-
- # step through the value list.
- self.value=self.values[self.mutant_index]
-
- # increment the mutation count.
- self.mutant_index+=1
-
- returnTrue
-
-
[docs]defnum_mutations(self):
- '''
- Number of values in this primitive.
-
- @rtype: Integer
- @return: Number of values in this primitive.
- '''
-
- returnlen(self.values)
[docs]classrandom_data(base_primitive):
- def__init__(self,value,min_length,max_length,max_mutations=25,fuzzable=True,step=None,name=None):
- '''
- Generate a random chunk of data while maintaining a copy of the original. A random length range can be specified.
- For a static length, set min/max length to be the same.
-
- @type value: Raw
- @param value: Original value
- @type min_length: Integer
- @param min_length: Minimum length of random block
- @type max_length: Integer
- @param max_length: Maximum length of random block
- @type max_mutations: Integer
- @param max_mutations: (Optional, def=25) Number of mutations to make before reverting to default
- @type fuzzable: Boolean
- @param fuzzable: (Optional, def=True) Enable/disable fuzzing of this primitive
- @type step: Integer
- @param step: (Optional, def=None) If not null, step count between min and max reps, otherwise random
- @type name: String
- @param name: (Optional, def=None) Specifying a name gives you direct access to a primitive
- '''
-
- super(random_data,self).__init__()
- self.value=self.original_value=str(value)
- self.min_length=min_length
- self.max_length=max_length
- self.max_mutations=max_mutations
- self.fuzzable=fuzzable
- self.step=step
- self.name=name
-
- self.s_type="random_data"# for ease of object identification
-
- ifself.step:
- self.max_mutations=(self.max_length-self.min_length)//self.step+1
-
-
[docs]defmutate(self):
- '''
- Mutate the primitive value returning False on completion.
-
- @rtype: Boolean
- @return: True on success, False otherwise.
- '''
-
- # if we've ran out of mutations, raise the completion flag.
- ifself.mutant_index==self.num_mutations():
- self.fuzz_complete=True
-
- # if fuzzing was disabled or complete, and mutate() is called, ensure the original value is restored.
- ifnotself.fuzzableorself.fuzz_complete:
- self.value=self.original_value
- returnFalse
-
- # select a random length for this string.
- ifnotself.step:
- length=random.randint(self.min_length,self.max_length)
- # select a length function of the mutant index and the step.
- else:
- length=self.min_length+self.mutant_index*self.step
-
- # reset the value and generate a random string of the determined length.
- self.value=b""
- foriinrange(length):
- self.value+=struct.pack("B",random.randint(0,255))
-
- # increment the mutation count.
- self.mutant_index+=1
-
- returnTrue
-
-
[docs]defnum_mutations(self):
- '''
- Calculate and return the total number of mutations for this individual primitive.
-
- @rtype: Integer
- @return: Number of mutated forms this primitive can take
- '''
-
- returnself.max_mutations
[docs]classstatic(base_primitive):
- def__init__(self,value,name=None):
- '''
- Primitive that contains static content.
-
- @type value: Raw
- @param value: Raw static data
- @type name: String
- @param name: (Optional, def=None) Specifying a name gives you direct access to a primitive
- '''
-
- super(static,self).__init__()
- self.value=self.original_value=value
- self.name=name
- self.fuzzable=False# every primitive needs this attribute.
- self.s_type="static"# for ease of object identification
- self.fuzz_complete=True
-
-
[docs]classstring(base_primitive):
- # store fuzz_library as a class variable to avoid copying the ~70MB structure across each instantiated primitive.
- fuzz_library=[]
-
- def__init__(self,value,size=-1,padding="\x00",encoding="ascii",fuzzable=True,max_len=0,name=None):
- '''
- Primitive that cycles through a library of "bad" strings. The class variable 'fuzz_library' contains a list of
- smart fuzz values global across all instances. The 'this_library' variable contains fuzz values specific to
- the instantiated primitive. This allows us to avoid copying the near ~70MB fuzz_library data structure across
- each instantiated primitive.
-
- @type value: String
- @param value: Default string value
- @type size: Integer
- @param size: (Optional, def=-1) Static size of this field, leave -1 for dynamic.
- @type padding: Character
- @param padding: (Optional, def="\\x00") Value to use as padding to fill static field size.
- @type encoding: String
- @param encoding: (Optonal, def="ascii") String encoding, ex: utf_16_le for Microsoft Unicode.
- @type fuzzable: Boolean
- @param fuzzable: (Optional, def=True) Enable/disable fuzzing of this primitive
- @type max_len: Integer
- @param max_len: (Optional, def=0) Maximum string length
- @type name: String
- @param name: (Optional, def=None) Specifying a name gives you direct access to a primitive
- '''
-
- super(string,self).__init__()
- self.value=self.original_value=value
- self.size=size
- self.padding=padding
- self.encoding=encoding
- self.fuzzable=fuzzable
- self.name=name
-
- self.s_type="string"# for ease of object identification
-
- # add this specific primitives repitition values to the unique fuzz library.
- self.this_library= \
- [
- self.value*2,
- self.value*10,
- self.value*100,
-
- # UTF-8
- self.value*2+"\xfe",
- self.value*10+"\xfe",
- self.value*100+"\xfe",
- ]
-
- # if the fuzz library has not yet been initialized, do so with all the global values.
- ifnotself.fuzz_library:
- string.fuzz_library= \
- [
- # omission.
- "",
-
- # strings ripped from spike (and some others I added)
- "/.:/"+"A"*5000+"\x00\x00",
- "/.../"+"A"*5000+"\x00\x00",
- "/.../.../.../.../.../.../.../.../.../.../",
- "/../../../../../../../../../../../../etc/passwd",
- "/../../../../../../../../../../../../boot.ini",
- "..:..:..:..:..:..:..:..:..:..:..:..:..:",
- "\\\\*",
- "\\\\?\\",
- "/\\"*5000,
- "/."*5000,
- "!@#$%%^#$%#$@#$%$$@#$%^^**(()",
- "%01%02%03%04%0a%0d%0aADSF",
- "%01%02%03@%04%0a%0d%0aADSF",
- "/%00/",
- "%00/",
- "%00",
- "%u0000",
- "%\xfe\xf0%\x00\xff",
- "%\xfe\xf0%\x01\xff"*20,
-
- # format strings.
- "%n"*100,
- "%n"*500,
- "\"%n\""*500,
- "%s"*100,
- "%s"*500,
- "\"%s\""*500,
-
- # command injection.
- "|touch /tmp/SULLEY",
- ";touch /tmp/SULLEY;",
- "|notepad",
- ";notepad;",
- "\nnotepad\n",
-
- # SQL injection.
- "1;SELECT%20*",
- "'sqlattempt1",
- "(sqlattempt2)",
- "OR%201=1",
-
- # some binary strings.
- "\xde\xad\xbe\xef",
- "\xde\xad\xbe\xef"*10,
- "\xde\xad\xbe\xef"*100,
- "\xde\xad\xbe\xef"*1000,
- "\xde\xad\xbe\xef"*10000,
- "\x00"*1000,
-
- # miscellaneous.
- "\r\n"*100,
- "<>"*500,# sendmail crackaddr (http://lsd-pl.net/other/sendmail.txt)
- ]
-
- # add some long strings.
- self.add_long_strings("A")
- self.add_long_strings("B")
- self.add_long_strings("1")
- self.add_long_strings("2")
- self.add_long_strings("3")
- self.add_long_strings("<")
- self.add_long_strings(">")
- self.add_long_strings("'")
- self.add_long_strings("\"")
- self.add_long_strings("/")
- self.add_long_strings("\\")
- self.add_long_strings("?")
- self.add_long_strings("=")
- self.add_long_strings("a=")
- self.add_long_strings("&")
- self.add_long_strings(".")
- self.add_long_strings(",")
- self.add_long_strings("(")
- self.add_long_strings(")")
- self.add_long_strings("]")
- self.add_long_strings("[")
- self.add_long_strings("%")
- self.add_long_strings("*")
- self.add_long_strings("-")
- self.add_long_strings("+")
- self.add_long_strings("{")
- self.add_long_strings("}")
- self.add_long_strings("\x14")
- self.add_long_strings("\xFE")# expands to 4 characters under utf16
- self.add_long_strings("\xFF")# expands to 4 characters under utf16
-
- # add some long strings with null bytes thrown in the middle of it.
- forlengthin[128,256,1024,2048,4096,32767,0xFFFF]:
- s="B"*length
- s=s[:len(s)//2]+"\x00"+s[len(s)//2:]
- string.fuzz_library.append(s)
-
- # if the optional file '.fuzz_strings' is found, parse each line as a new entry for the fuzz library.
- try:
- fh=open(".fuzz_strings","r")
-
- forfuzz_stringinfh.readlines():
- fuzz_string=fuzz_string.rstrip("\r\n")
-
- iffuzz_string!="":
- string.fuzz_library.append(fuzz_string)
-
- fh.close()
- except:
- pass
-
- # delete strings which length is greater than max_len.
- ifmax_len>0:
- ifany(len(s)>max_lenforsinself.this_library):
- self.this_library=list(set([s[:max_len]forsinself.this_library]))
-
- ifany(len(s)>max_lenforsinself.fuzz_library):
- self.fuzz_library=list(set([s[:max_len]forsinself.fuzz_library]))
-
-
[docs]defadd_long_strings(self,sequence):
- '''
- Given a sequence, generate a number of selectively chosen strings lengths of the given sequence and add to the
- string heuristic library.
-
- @type sequence: String
- @param sequence: Sequence to repeat for creation of fuzz strings.
- '''
-
- forlengthin[128,255,256,257,511,512,513,1023,1024,2048,2049,4095,4096,4097,5000,10000,20000,
- 32762,32763,32764,32765,32766,32767,32768,32769,0xFFFF-2,0xFFFF-1,0xFFFF,0xFFFF+1,
- 0xFFFF+2,99999,100000,500000,1000000]:
-
- long_string=sequence*length
- string.fuzz_library.append(long_string)
-
-
[docs]defmutate(self):
- '''
- Mutate the primitive by stepping through the fuzz library extended with the "this" library, return False on
- completion.
-
- @rtype: Boolean
- @return: True on success, False otherwise.
- '''
-
- # loop through the fuzz library until a suitable match is found.
- while1:
- # if we've ran out of mutations, raise the completion flag.
- ifself.mutant_index==self.num_mutations():
- self.fuzz_complete=True
-
- # if fuzzing was disabled or complete, and mutate() is called, ensure the original value is restored.
- ifnotself.fuzzableorself.fuzz_complete:
- self.value=self.original_value
- returnFalse
-
- # update the current value from the fuzz library.
- self.value=(self.fuzz_library+self.this_library)[self.mutant_index]
-
- # increment the mutation count.
- self.mutant_index+=1
-
- # if the size parameter is disabled, break out of the loop right now.
- ifself.size==-1:
- break
-
- # ignore library items greater then user-supplied length.
- # TODO: might want to make this smarter.
- iflen(self.value)>self.size:
- continue
-
- # pad undersized library items.
- iflen(self.value)<self.size:
- self.value=self.value+self.padding*(self.size-len(self.value))
- break
-
- returnTrue
-
-
[docs]defnum_mutations(self):
- '''
- Calculate and return the total number of mutations for this individual primitive.
-
- @rtype: Integer
- @return: Number of mutated forms this primitive can take
- '''
-
- returnlen(self.fuzz_library)+len(self.this_library)
-
-
[docs]defrender(self):
- '''
- Render the primitive, encode the string according to the specified encoding.
- '''
-
- # try to encode the string properly and fall back to the default value on failure.
- try:
- self.rendered=str(self.value).encode(self.encoding)
- except:
- self.rendered=str(self.value).encode('latin-1')
-
- returnself.rendered
[docs]classbit_field(base_primitive):
- def__init__(self,value,width,max_num=None,endian="<",format="binary",signed=False,full_range=False,fuzzable=True,name=None):
- '''
- The bit field primitive represents a number of variable length and is used to define all other integer types.
-
- @type value: Integer
- @param value: Default integer value
- @type width: Integer
- @param width: Width of bit fields
- @type endian: Character
- @param endian: (Optional, def=LITTLE_ENDIAN) Endianess of the bit field (LITTLE_ENDIAN: <, BIG_ENDIAN: >)
- @type format: String
- @param format: (Optional, def=binary) Output format, "binary" or "ascii"
- @type signed: Boolean
- @param signed: (Optional, def=False) Make size signed vs. unsigned (applicable only with format="ascii")
- @type full_range: Boolean
- @param full_range: (Optional, def=False) If enabled the field mutates through *all* possible values.
- @type fuzzable: Boolean
- @param fuzzable: (Optional, def=True) Enable/disable fuzzing of this primitive
- @type name: String
- @param name: (Optional, def=None) Specifying a name gives you direct access to a primitive
- '''
-
- super(bit_field,self).__init__()
- assertisinstance(width,int)
-
- ifisinstance(value,(int,list,tuple)):
- self.value=self.original_value=value
- else:
- raiseValueError("The supplied value must be either an Int, Long, List or Tuple.")
-
- self.width=width
- self.max_num=max_num
- self.endian=endian
- self.format=format
- self.signed=signed
- self.full_range=full_range
- self.fuzzable=fuzzable
- self.name=name
-
- self.rendered=b""# rendered value
- self.cyclic_index=0# when cycling through non-mutating values
-
- ifself.max_numisNone:
- self.max_num=self.to_decimal("1"+"0"*width)
-
- assertisinstance(self.max_num,int)
-
- # build the fuzz library.
- ifself.full_range:
- # add all possible values.
- foriinrange(0,self.max_num):
- self.fuzz_library.append(i)
- else:
- ifisinstance(value,(list,tuple)):
- # Use the supplied values as the fuzz library.
- forvalinvalue:
- self.fuzz_library.append(val)
- else:
- # try only "smart" values.
- self.add_integer_boundaries(0)
- self.add_integer_boundaries(self.max_num//2)
- self.add_integer_boundaries(self.max_num//3)
- self.add_integer_boundaries(self.max_num//4)
- self.add_integer_boundaries(self.max_num//8)
- self.add_integer_boundaries(self.max_num//16)
- self.add_integer_boundaries(self.max_num//32)
- self.add_integer_boundaries(self.max_num)
-
- # if the optional file '.fuzz_ints' is found, parse each line as a new entry for the fuzz library.
- try:
- fh=open(".fuzz_ints","r")
-
- forfuzz_intinfh.readlines():
- # convert the line into an integer, continue on failure.
- try:
- fuzz_int=int(fuzz_int,16)
- except:
- continue
-
- iffuzz_int<self.max_num:
- self.fuzz_library.append(fuzz_int)
-
- fh.close()
- except:
- pass
-
-
[docs]defadd_integer_boundaries(self,integer):
- '''
- Add the supplied integer and border cases to the integer fuzz heuristics library.
-
- @type integer: Int
- @param integer: Integer to append to fuzz heuristics
- '''
-
- foriinrange(-10,10):
- case=integer+i
-
- # ensure the border case falls within the valid range for this field.
- if0<=case<self.max_num:
- ifcasenotinself.fuzz_library:
- self.fuzz_library.append(case)
-
-
[docs]defrender(self):
- '''
- Render the primitive.
- '''
-
- #
- # binary formatting.
- #
-
- ifself.format=="binary":
- bit_stream=""
- rendered=b""
-
- # pad the bit stream to the next byte boundary.
- ifself.width%8==0:
- bit_stream+=self.to_binary()
- else:
- bit_stream="0"*(8-(self.width%8))
- bit_stream+=self.to_binary()
-
- # convert the bit stream from a string of bits into raw bytes.
- foriinrange(len(bit_stream)//8):
- chunk=bit_stream[8*i:8*i+8]
- rendered+=struct.pack("B",self.to_decimal(chunk))
-
- # if necessary, convert the endianess of the raw bytes.
- ifself.endian=="<":
- rendered=rendered[::-1]
-
- self.rendered=rendered
-
- #
- # ascii formatting.
- #
-
- else:
- # if the sign flag is raised and we are dealing with a signed integer (first bit is 1).
- ifself.signedandself.to_binary()[0]=="1":
- max_num=self.to_decimal("1"+"0"*(self.width-1))
-
- # mask off the sign bit.
- val=self.value&self.to_decimal("1"*(self.width-1))
-
- # account for the fact that the negative scale works backwards.
- val=max_num-val-1
-
- # toss in the negative sign.
- self.rendered="%d"%~val
-
- # unsigned integer or positive signed integer.
- else:
- self.rendered="%d"%self.value
- returnself.rendered
-
-
[docs]defto_binary(self,number=None,bit_count=None):
- '''
- Convert a number to a binary string.
-
- @type number: Integer
- @param number: (Optional, def=self.value) Number to convert
- @type bit_count: Integer
- @param bit_count: (Optional, def=self.width) Width of bit string
-
- @rtype: String
- @return: Bit string
- '''
- ifnumberisNone:
- ifisinstance(self.value,(list,tuple)):
- # We have been given a list to cycle through that is not being mutated...
- ifself.cyclic_index==len(self.value):
- # Reset the index.
- self.cyclic_index=0
- number=self.value[self.cyclic_index]
- self.cyclic_index+=1
- else:
- number=self.value
-
- ifbit_countisNone:
- bit_count=self.width
-
- return"".join(map(lambdax:str((number>>x)&1),range(bit_count-1,-1,-1)))
-
-
[docs]defto_decimal(self,binary):
- '''
- Convert a binary string to a decimal number.
-
- @type binary: String
- @param binary: Binary string
-
- @rtype: Integer
- @return: Converted bit string
- '''
-
- returnint(binary,2)
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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
-#
-
-"""
-HAL component providing access to and decoding of ACPI tables
-"""
-
-__version__='0.1'
-
-importstruct
-fromtypingimportDict,List,Tuple,Optional,Callable,Union
-fromcollectionsimportdefaultdict
-fromcollectionsimportnamedtuple
-
-fromchipsec.definesimportbytestostring
-fromchipsec.exceptionsimportUnimplementedAPIError
-fromchipsec.fileimportread_file
-fromchipsec.halimportacpi_tables
-fromchipsec.hal.hal_baseimportHALBase
-fromchipsec.hal.uefiimportUEFI
-fromchipsec.loggerimportlogger,print_buffer_bytes
-fromchipsec.hal.acpi_tablesimportACPI_TABLE
-
-# ACPI Table Header Format
-ACPI_TABLE_HEADER_FORMAT='=4sIBB6s8sI4sI'
-ACPI_TABLE_HEADER_SIZE=struct.calcsize(ACPI_TABLE_HEADER_FORMAT)# 36
-assert36==ACPI_TABLE_HEADER_SIZE
-
-
-
-
- #
- # Populates a list of ACPI tables available on the system
- #
-
[docs]defget_ACPI_table_list(self)->Dict[str,List[int]]:
- try:
- # 1. Try to extract ACPI table(s) from physical memory
- # read_physical_mem can be implemented using both
- # CHIPSEC kernel module and OS native API
- logger().log_hal("[acpi] Trying to enumerate ACPI tables from physical memory...")
- # find RSDT/XSDT table
- (is_xsdt,sdt_pa,sdt,sdt_header)=self.get_SDT()
-
- # cache RSDT/XSDT in the list of ACPI tables
- if(sdt_paisnotNone)and(sdt_headerisnotNone):
- self.tableList[bytestostring(sdt_header.Signature)].append(sdt_pa)
- ifsdtisnotNone:
- self.get_table_list_from_SDT(sdt,is_xsdt)
- self.get_DSDT_from_FADT()
- exceptUnimplementedAPIError:
- # 2. If didn't work, try using get_ACPI_table if a helper implemented
- # reading ACPI tables via native API which some OS may provide
- logger().log_hal("[acpi] Trying to enumerate ACPI tables using get_ACPI_table...")
- fortinACPI_TABLES.keys():
- table=self.cs.helper.get_ACPI_table(t)
- iftable:
- self.tableList[t].append(0)
-
- returnself.tableList
-
- #
- # Gets table list from entries in RSDT/XSDT
- #
-
[docs]defget_table_list_from_SDT(self,sdt:RsdtXsdt,is_xsdt:bool)->None:
- logger().log_hal(f'[acpi] Getting table list from entries in {"XSDT"ifis_xsdtelse"RSDT"}')
- forainsdt.Entries:
- _sig=self.cs.mem.read_physical_mem(a,ACPI_TABLE_SIG_SIZE)
- _sig=bytestostring(_sig)
- if_signotinACPI_TABLES.keys():
- iflogger().HAL:
- logger().log_warning(f'Unknown ACPI table signature: {_sig}')
- self.tableList[_sig].append(a)
-
- #
- # Prints a list of ACPI tables available on the system
- #
-
[docs]defprint_ACPI_table_list(self)->None:
- iflen(self.tableList)==0:
- logger().log_error("Couldn't get a list of ACPI tables")
- else:
- logger().log_hal('[acpi] Found the following ACPI tables:')
- fortableNameinsorted(self.tableList.keys()):
- table_values_str=', '.join([f'0x{addr:016X}'foraddrinself.tableList[tableName]])
- logger().log(f' - {tableName}: {table_values_str}')
-
- #
- # Retrieves contents of ACPI table from memory or from file
- #
-
[docs]defget_ACPI_table(self,name:str,isfile:bool=False)->List[Tuple[bytes,bytes]]:
- acpi_tables_data:List[bytes]=[]
- ifisfile:
- acpi_tables_data.append(read_file(name))
- else:
- try:
- # 1. Try to extract ACPI table(s) from physical memory
- # read_physical_mem can be implemented using both
- # CHIPSEC kernel module and OS native API
- logger().log_hal('[acpi] trying to extract ACPI table from physical memory...')
- fortable_addressinself.tableList[name]:
- t_size=self.cs.mem.read_physical_mem_dword(table_address+4)
- t_data=self.cs.mem.read_physical_mem(table_address,t_size)
- acpi_tables_data.append(t_data)
- exceptUnimplementedAPIError:
- # 2. If didn't work, try using get_ACPI_table if a helper implemented
- # reading ACPI tables via native API which some OS may provide
- logger().log_hal("[acpi] trying to extract ACPI table using get_ACPI_table...")
- t_data=self.cs.helper.get_ACPI_table(name)
- acpi_tables_data.append(t_data)
-
- acpi_tables=[]
- fordatainacpi_tables_data:
- acpi_tables.append((data[:ACPI_TABLE_HEADER_SIZE],data[ACPI_TABLE_HEADER_SIZE:]))
-
- returnacpi_tables
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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
-# Authors:
-# Sarah Van Sickle, INTEL DCG RED team
-#
-
-
-"""
-HAL component decoding various ACPI tables
-"""
-
-__version__='0.1'
-
-importstruct
-fromcollectionsimportnamedtuple
-fromuuidimportUUID
-fromtypingimportList,Optional,Tuple
-fromchipsec.loggerimportlogger,dump_buffer_bytes
-fromchipsec.hal.uefi_commonimportEFI_GUID_FMT,EFI_GUID_STR
-
-
-
[docs]defplatCapStruct(self,tableLen:int,table_content:bytes)->str:
- highestValidCap=struct.unpack('<B',table_content[4:5])[0]
- reserved1_1=struct.unpack('<B',table_content[5:6])[0]
- reserved1_2=struct.unpack('<B',table_content[6:7])[0]
- reserved1_3=struct.unpack('<B',table_content[7:8])[0]
- capabilities=struct.unpack('<L',table_content[8:12])[0]
- cap1=capabilities&1
- cap2=capabilities&2
- cap3=capabilities&4
- capRes=capabilities&~(7)
- reserved2=struct.unpack('<L',table_content[12:16])[0]
- ifcap1==1:
- cap1_str='Platform ensures the entire CPU store data path is flushed to persistent memory on system power loss'
- else:
- cap1_str='Platform does not ensure the entire CPU store data path is flushed to persistent memory on system power loss'
- ifcap2==2:
- cap2_str='Platform provides mehanisms to automatically flush outstanding write data from the memory controller to persistent memory in the event of power loss'
- else:
- ifcap1==1:
- cap2_str='Platform does not provides mehanisms to automatically flush outstanding write data from the memory controller to persistent memory in the event of power loss'
- else:
- cap2_str='This should be set to 1 - Platform does not support'
- ifcap3==4:
- cap3_str='Platform supports mirroring multiple byte addressable persistent memory regions together'
- else:
- cap3_str='Platform does not support mirroring multiple byte addressable persistent memory regions together'
- returnf'''
- Platform Capabilities Structure [Type 7]
- Length : 0x{tableLen:04X} ( {tableLen:d} bytes )
- Highest Valid Capability : 0x{highestValidCap:02X}
- Reserved : 0x{reserved1_1:02X} 0x{reserved1_2:02X} 0x{reserved1_3:02X}
- Capabilities : 0x{capabilities:08X}
- CPU Cache Flush to NVDIMM Durability on Power Loss : 0x{cap1:08X} - {cap1_str}
- Mem Controller Flush to NVDIMM Durability on Power Loss : 0x{cap2:08X} - {cap2_str}
- Byte Addressible Persistent Mem Hw Mirroring Capable : 0x{cap3:08X} - {cap3_str}
- Reserved : 0x{capRes:08X}
- Reserved : 0x{reserved2:08X}
-'''
-
-
[docs]defflushHintAddrStruct(self,tableLen:int,table_content:bytes)->Tuple[int,str]:
- nfitDevHandle=struct.unpack('<L',table_content[4:8])[0]
- numFlushHintAddr=struct.unpack('<L',table_content[4:8])[0]
- reserved=struct.unpack('<L',table_content[4:8])[0]
- curLine=0
- lines=''
- whilecurLine<numFlushHintAddr:
- lineInfo=struct.unpack('<Q',table_content[curLine*8+8:curLine*8+16])[0]
- lines+=f'''
- Flush Hint Address {curLine+1:d} : 0x{lineInfo:016X} '''
- curLine+=1
- return(curLine-1)*8+16,f'''
- Flush Hint Address Structure [Type 6]
- Length : 0x{tableLen:04X} ( {tableLen:d} bytes )
- NFIT Device Handle : 0x{nfitDevHandle:08X}
- Number of Flush Hint Addresses in this Structure : 0x{numFlushHintAddr:08X} ( {numFlushHintAddr:d} )
- Reserved : 0x{reserved:08X}
- Flush Hint Addresses{lines}
-'''
-
-
[docs]defnvdimmBlockDataWindowsRegionStruct(self,tableLen:int,table_content:bytes)->str:
- nvdimmControlRegionStructureIndex=struct.unpack('<H',table_content[4:6])[0]
- numBlockDataWindows=struct.unpack('<H',table_content[6:8])[0]
- blockDataWindowsStartOffset=struct.unpack('<Q',table_content[8:16])[0]
- szBlckDataWindow=struct.unpack('<Q',table_content[16:24])[0]
- blckAccMemCap=struct.unpack('<Q',table_content[24:32])[0]
- begAddr=struct.unpack('<Q',table_content[32:40])[0]
- returnf'''
- NVDIMM Block Data Region Structure [Type 5]
- Length : 0x{tableLen:04X} ( {tableLen:d} bytes )
- NVDIMM Control Region Structure Index : 0x{nvdimmControlRegionStructureIndex:04X} - Should not be 0
- Number of Block Data Windows : 0x{numBlockDataWindows:04X} ( {numBlockDataWindows:d} )
- Block Data Window Start Offest : 0x{blockDataWindowsStartOffset:016X} ( {blockDataWindowsStartOffset:d} bytes )
- Size of Block Data Window : 0x{szBlckDataWindow:016X} ( {szBlckDataWindow:d} bytes )
- Block Accessible Memory Capacity : 0x{blckAccMemCap:016X} ( {blckAccMemCap:d} bytes )
- Start Addr for 1st Block in Block Accessible Mem : 0x{begAddr:016X} ( {begAddr:d} bytes )
-'''
-
-
[docs]defnvdimmControlRegionStructMark(self,tableLen:int,table_content:bytes)->str:
- nvdimmControlRegionStructureIndex=struct.unpack('<H',table_content[4:6])[0]
- vendorID=struct.unpack('<H',table_content[6:8])[0]
- deviceID=struct.unpack('<H',table_content[8:10])[0]
- revID=struct.unpack('<H',table_content[10:12])[0]
- subsystemVendorID=struct.unpack('<H',table_content[12:14])[0]
- subsysDevID=struct.unpack('<H',table_content[14:16])[0]
- subsysRevID=struct.unpack('<H',table_content[16:18])[0]
- validFields=struct.unpack('<B',table_content[18:19])[0]
- manLocation=struct.unpack('<B',table_content[19:20])[0]
- manDate=struct.unpack('<H',table_content[20:22])[0]
- # need more parsing of the date
- reserved=struct.unpack('<H',table_content[22:24])[0]
- serialNum=struct.unpack('<L',table_content[24:28])[0]
- regionFormatInterfaceCode=struct.unpack('<H',table_content[28:30])[0]
- rfic1=struct.unpack('<B',table_content[28:29])[0]
- rfic2=struct.unpack('<B',table_content[29:30])[0]
- rfic_r1=rfic1&224
- rfic_fif=rfic1&31
- rfic_r2=rfic2&224
- rfic_fcf=rfic2&31
- numBlockControlWindows=struct.unpack('<H',table_content[30:32])[0]
- cont_str='ERROR - Table is shorter than expected.'
- ifnumBlockControlWindows!=0:
- szBlckControlWindow=struct.unpack('<Q',table_content[32:40])[0]
- commandRegOffset=struct.unpack('<Q',table_content[40:48])[0]
- szCommandReg=struct.unpack('<Q',table_content[48:56])[0]
- statusRegOffset=struct.unpack('<Q',table_content[56:64])[0]
- szStatus=struct.unpack('<Q',table_content[64:72])[0]
- nvdimmControlRegionFl=struct.unpack('<H',table_content[72:74])[0]
- reserved2_1=struct.unpack('<B',table_content[74:75])[0]
- reserved2_2=struct.unpack('<B',table_content[75:76])[0]
- reserved2_3=struct.unpack('<B',table_content[76:77])[0]
- reserved2_4=struct.unpack('<B',table_content[77:78])[0]
- reserved2_5=struct.unpack('<B',table_content[78:79])[0]
- reserved2_6=struct.unpack('<B',table_content[79:80])[0]
- cont_str=f''' Size of Block Control Windows : 0x{szBlckControlWindow:016X} ({szBlckControlWindow:d} bytes)
- Command Reg Offset in Block Control Windows : 0x{commandRegOffset:016X}
- Size of Command Register in Block Control Windows : 0x{szCommandReg:016X}
- Status Register Offset in Block Control Windows : 0x{statusRegOffset:016X}
- Size of Status Register in Block Control Windows : 0x{szStatus:016X}
- NVDIMM Control Region Flag : 0x{nvdimmControlRegionFl:04X}
- Reserved : 0x{reserved2_1:02X} 0x{reserved2_2:02X} 0x{reserved2_3:02X} 0x{reserved2_4:02X} 0x{reserved2_5:02X} 0x{reserved2_6:02X}
-{cont_str}'''
- valid_0=validFields&1
- valid_str=''
- valid_man_str=''
- ifvalid_0==0:
- valid_str='System is compliant with ACPI 6.0 - Manufacturing Location & Date fields are invalid and should be ignored'
- valid_man_str='Value is invalid and should be ignored'
- returnf'''
- NVDIMM Control Region Structure [Type 4]
- Length : 0x{tableLen:04X} ( {tableLen:d} bytes )
- NVDIMM Control Region Structure Index : 0x{nvdimmControlRegionStructureIndex:04X}
- Vendor ID : 0x{vendorID:04X}
- Device ID : 0x{deviceID:04X}
- Revision ID : 0x{revID:04X}
- Subsystem Vendor ID : 0x{subsystemVendorID:04X}
- Subsystem Device ID : 0x{subsysDevID:04X}
- Subsystem Revision ID : 0x{subsysRevID:04X}
- Valid Fields : 0x{validFields:02X}
- Bit[0] : {valid_0}{valid_str}
- Manufacturing Location : 0x{manLocation:02X}{valid_man_str}
- Manufacturing Date : 0x{manDate:04X}{valid_man_str}
- Reserved : 0x{reserved:04X}
- Serial Number : 0x{serialNum:08X}
- Region Format Interface Code : 0x{regionFormatInterfaceCode:04X}
- Reserved : 0x{rfic_r1:02X}
- Function Interface Field : 0x{rfic_fif:02X}
- Reserved : 0x{rfic_r2:02X}
- Function Class Field : 0x{rfic_fcf:02X}
- Number of Block Control Windows : 0x{numBlockControlWindows:08X}
-'''
[docs]defparse(self,table_content:bytes)->None:
- self.results='''==================================================================
- Table Content
-=================================================================='''
- # Ensure can get identifier and dataOffset fields
- iflen(table_content)<18:
- return
- # Get Guid and Data Offset
- guid=struct.unpack(EFI_GUID_FMT,table_content[:16])[0]
- identifier=EFI_GUID_STR(guid)
- offset=struct.unpack('H',table_content[16:18])[0]
- self.results+=f"""
- identifier : {identifier}
- Data Offset : {offset:d}"""
- # check if SMM Communication ACPI Table
- ifnot(SMM_COMM_TABLE==identifier):
- return
- content_offset=offset-36
- # check to see if there is enough data to get SW SMI Number and Buffer Ptr Address
- ifcontent_offset<0orcontent_offset+12>len(table_content):
- return
- self.smi=struct.unpack('I',table_content[content_offset:content_offset+4])[0]
- content_offset+=4
- self.buf_addr=struct.unpack('Q',table_content[content_offset:content_offset+8])[0]
- content_offset+=8
- self.results+=f"""
- SW SMI NUM : {self.smi}
- Buffer Ptr Address : {self.buf_addr:X}"""
- # Check to see if there is enough data for Invocation Register
- ifcontent_offset+12<=len(table_content):
- self.invoc_reg=GAS(table_content[content_offset:content_offset+12])
- self.results+=f"\n Invocation Register :\n{str(self.invoc_reg)}"
- else:
- self.results+="\n Invocation Register : None\n"
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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: Platform Hardware Security Assessment Framework
-#
-# -------------------------------------------------------------------------------
-
-"""
-CMOS memory specific functions (dump, read/write)
-
-usage:
- >>> cmos.dump_low()
- >>> cmos.dump_high()
- >>> cmos.dump()
- >>> cmos.read_cmos_low( offset )
- >>> cmos.write_cmos_low( offset, value )
- >>> cmos.read_cmos_high( offset )
- >>> cmos.write_cmos_high( offset, value )
-"""
-fromtypingimportList
-fromchipsec.halimporthal_base
-importchipsec.logger
-
-CMOS_ADDR_PORT_LOW=0x70
-CMOS_DATA_PORT_LOW=0x71
-CMOS_ADDR_PORT_HIGH=0x72
-CMOS_DATA_PORT_HIGH=0x73
-
-
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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
-#
-
-
-"""
-CPU related functionality
-
-"""
-fromtypingimportDict,List,Tuple,Optional
-fromchipsec.halimportacpi,hal_base,paging
-fromchipsec.loggerimportlogger
-
-VMM_NONE=0
-VMM_XEN=0x1
-VMM_HYPER_V=0x2
-VMM_VMWARE=0x3
-VMM_KVM=0x4
-
-
-########################################################################################################
-#
-# CORES HAL Component
-#
-########################################################################################################
-
-
-
- # determine the cpu threads location within a package/core
-
[docs]defget_cpu_topology(self)->Dict[str,Dict[int,List[int]]]:
- num_threads=self.cs.helper.get_threads_count()
- packages:Dict[int,List[int]]={}
- cores:Dict[int,List[int]]={}
- forthreadinrange(num_threads):
- ifnum_threads>1:
- self.logger.log_hal(f'Setting affinity to: {thread:d}')
- self.cs.helper.set_affinity(thread)
- eax=0xb# cpuid leaf 0B contains x2apic info
- ecx=1# ecx 1 will get us pkg_id in edx after shifting right by _eax
- (_eax,_,_,_edx)=self.cs.cpu.cpuid(eax,ecx)
- pkg_id=_edx>>(_eax&0xf)
- ifpkg_idnotinpackages:
- packages[pkg_id]=[]
- packages[pkg_id].append(thread)
-
- ecx=0# ecx 0 will get us the core_id in edx after shifting right by _eax
- (_eax,_,_,_edx)=self.cs.cpu.cpuid(eax,ecx)
- core_id=_edx>>(_eax&0xf)
- ifcore_idnotincores:
- cores[core_id]=[]
- cores[core_id].append(thread)
- self.logger.log_hal(f'pkg id is {pkg_id:x}')
- self.logger.log_hal(f'core id is {core_id:x}')
- topology={'packages':packages,'cores':cores}
- returntopology
-
- # determine number of physical sockets using the CPUID and APIC ACPI table
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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
-#
-
-"""
-CPUID information
-
-usage:
- >>> cpuid(0)
-"""
-
-fromtypingimportTuple
-fromchipsec.halimporthal_base
-fromchipsec.loggerimportlogger
-
-
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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: Platform Hardware Security Assessment Framework
-#
-# -------------------------------------------------------------------------------
-
-"""
-Access to Embedded Controller (EC)
-
-Usage:
-
- >>> write_command( command )
- >>> write_data( data )
- >>> read_data()
- >>> read_memory( offset )
- >>> write_memory( offset, data )
- >>> read_memory_extended( word_offset )
- >>> write_memory_extended( word_offset, data )
- >>> read_range( start_offset, size )
- >>> write_range( start_offset, buffer )
-
-"""
-fromtypingimportList,Optional
-fromchipsec.halimporthal_base
-fromchipsec.loggerimportprint_buffer_bytes
-
-#
-# Embedded Controller ACPI ports
-#
-IO_PORT_EC_DATA=0x62
-IO_PORT_EC_COMMAND=0x66
-IO_PORT_EC_STATUS=0x66
-
-IO_PORT_EC_INDEX=0x380
-IO_PORT_EC_INDEX_ADDRH=(IO_PORT_EC_INDEX+0x1)
-IO_PORT_EC_INDEX_ADDRL=(IO_PORT_EC_INDEX+0x2)
-IO_PORT_EC_INDEX_DATA=(IO_PORT_EC_INDEX+0x3)
-
-
-EC_STS_OBF=0x01# EC Output buffer full
-EC_STS_IBF=0x02# EC Input buffer empty
-
-
-#
-# Embedded Controller ACPI commands
-# These commands should be submitted to EC ACPI I/O ports
-#
-EC_COMMAND_ACPI_READ=0x080# Read EC ACPI memory
-EC_COMMAND_ACPI_WRITE=0x081# Write EC ACPI memory
-EC_COMMAND_ACPI_LOCK=0x082# Lock EC for burst use
-EC_COMMAND_ACPI_UNLOCK=0x083# Unlock EC from burst use
-EC_COMMAND_ACPI_QUERY=0x084# Query EC event
-EC_COMMAND_ACPI_READ_EXT=0x0F0# Read EC ACPI extended memory
-EC_COMMAND_ACPI_WRITE_EXT=0x0F1# Write EC ACPI extended memory
-
-
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-2016, 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
-#
-
-
-"""
-Base for HAL Components
-"""
-
-importchipsec.logger
-
-
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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: Platform Hardware Security Assessment Framework
-#
-# -------------------------------------------------------------------------------
-
-"""
-Working with Intel processor Integrated Graphics Device (IGD)
-
-usage:
- >>> gfx_aperture_dma_read(0x80000000, 0x100)
-"""
-
-fromtypingimportOptional,Tuple
-fromchipsec.halimporthal_base
-fromchipsec.loggerimportprint_buffer_bytes
-
-
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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
-#
-
-"""
-Functionality encapsulating interrupt generation
-CPU Interrupts specific functions (SMI, NMI)
-
-usage:
- >>> send_SMI_APMC( 0xDE )
- >>> send_NMI()
-"""
-
-# TODO IPIs through Local APIC??
-
-importstruct
-importuuid
-fromtypingimportOptional,Tuple
-fromchipsec.halimporthal_base
-fromchipsec.loggerimportlogger,print_buffer_bytes
-fromchipsec.hal.acpiimportACPI
-fromchipsec.hal.acpi_tablesimportUEFI_TABLE,GAS
-fromchipsec.definesimportbytestostring
-
-SMI_APMC_PORT=0xB2
-SMI_DATA_PORT=0xB3
-
-NMI_TCO1_CTL=0x8# NMI_NOW is bit [8] in TCO1_CTL (or bit [1] in TCO1_CTL + 1)
-NMI_NOW=0x1
-
-
-
-
- '''
-Send SWSMI in the same way as EFI_SMM_COMMUNICATION_PROTOCOL
- - Write Commbuffer location and Commbuffer size to 'smmc' structure
- - Write 0 to 0xb3 and 0xb2
-
-MdeModulePkg/Core/PiSmmCore/PiSmmCorePrivateData.h
-
-#define SMM_CORE_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('s', 'm', 'm', 'c')
- struct {
- UINTN Signature;
- This field is used by the SMM Communicatioon Protocol to pass a buffer into
- a software SMI handler and for the software SMI handler to pass a buffer back to
- the caller of the SMM Communication Protocol.
- VOID *CommunicationBuffer;
- UINTN BufferSize;
-
- EFI_STATUS ReturnStatus;
-} SMM_CORE_PRIVATE_DATA;
- '''
-
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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
-#
-
-
-"""
-Access to Port I/O
-
-usage:
- >>> read_port_byte( 0x61 )
- >>> read_port_word( 0x61 )
- >>> read_port_dword( 0x61 )
- >>> write_port_byte( 0x71, 0 )
- >>> write_port_word( 0x71, 0 )
- >>> write_port_dword( 0x71, 0 )
-"""
-
-fromtypingimportList
-fromchipsec.loggerimportlogger
-
-
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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
-#
-
-
-"""
-I/O BAR access (dump, read/write)
-
-usage:
- >>> get_IO_BAR_base_address( bar_name )
- >>> read_IO_BAR_reg( bar_name, offset, size )
- >>> write_IO_BAR_reg( bar_name, offset, size, value )
- >>> dump_IO_BAR( bar_name )
-"""
-fromtypingimportTuple,List
-fromchipsec.halimporthal_base
-fromchipsec.loggerimportlogger
-fromchipsec.exceptionsimportIOBARNotFoundError
-fromchipsec.exceptionsimportCSReadError
-
-DEFAULT_IO_BAR_SIZE=0x100
-
-
-
[docs]classIOBAR(hal_base.HALBase):
-
- def__init__(self,cs):
- super(IOBAR,self).__init__(cs)
-
- #
- # Check if I/O BAR with bar_name has been defined in XML config
- # Use this function to fall-back to hardcoded config in case XML config is not available
- #
-
[docs]defis_IO_BAR_defined(self,bar_name:str)->bool:
- try:
- return(self.cs.Cfg.IO_BARS[bar_name]isnotNone)
- exceptKeyError:
- iflogger().HAL:
- logger().log_error(f"'{bar_name}' I/O BAR definition not found in XML config")
- returnFalse
-
- #
- # Get base address of I/O range by IO BAR name
- #
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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
-#
-
-
-"""
-Access to IOMMU engines
-"""
-
-fromchipsec.halimporthal_base,mmio,paging
-fromchipsec.exceptionsimportIOMMUError
-
-IOMMU_ENGINE_DEFAULT='VTD'
-IOMMU_ENGINE_GFX='GFXVTD'
-
-
-IOMMU_ENGINES={
- IOMMU_ENGINE_GFX:'GFXVTBAR',
- IOMMU_ENGINE_DEFAULT:'VTBAR'
-}
-
-
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2019-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
-#
-
-__version__='1.0'
-
-fromtypingimportList,Optional
-fromchipsec.definesimportbit,is_set
-fromchipsec.hal.hal_baseimportHALBase
-fromchipsec.exceptionsimportCSReadError,HWAccessViolationError
-
-
-
[docs]classLockResult:
- DEFINED=bit(0)# lock exists within configuration
- HAS_CONFIG=bit(1)# lock configuration exists
- LOCKED=bit(2)# lock matches value within xml
- CAN_READ=bit(3)# system is able to access the lock
- INCONSISTENT=bit(4)# all lock results do not match
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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
-#
-
-"""
-Access to MMIO (Memory Mapped IO) BARs and Memory-Mapped PCI Configuration Space (MMCFG)
-
-usage:
- >>> read_MMIO_reg(cs, bar_base, 0x0, 4)
- >>> write_MMIO_reg(cs, bar_base, 0x0, 0xFFFFFFFF, 4)
- >>> read_MMIO(cs, bar_base, 0x1000)
- >>> dump_MMIO(cs, bar_base, 0x1000)
-
- Access MMIO by BAR name:
-
- >>> read_MMIO_BAR_reg(cs, 'MCHBAR', 0x0, 4)
- >>> write_MMIO_BAR_reg(cs, 'MCHBAR', 0x0, 0xFFFFFFFF, 4)
- >>> get_MMIO_BAR_base_address(cs, 'MCHBAR')
- >>> is_MMIO_BAR_enabled(cs, 'MCHBAR')
- >>> is_MMIO_BAR_programmed(cs, 'MCHBAR')
- >>> dump_MMIO_BAR(cs, 'MCHBAR')
- >>> list_MMIO_BARs(cs)
-
- Access Memory Mapped Config Space:
-
- >>> get_MMCFG_base_address(cs)
- >>> read_mmcfg_reg(cs, 0, 0, 0, 0x10, 4)
- >>> read_mmcfg_reg(cs, 0, 0, 0, 0x10, 4, 0xFFFFFFFF)
-"""
-fromtypingimportList,Optional,Tuple
-fromchipsec.halimporthal_base
-fromchipsec.exceptionsimportCSReadError
-fromchipsec.loggerimportlogger
-fromchipsec.definesimportget_bits
-
-DEFAULT_MMIO_BAR_SIZE=0x1000
-
-PCI_PCIEXBAR_REG_LENGTH_256MB=0x0
-PCI_PCIEXBAR_REG_LENGTH_128MB=0x1
-PCI_PCIEXBAR_REG_LENGTH_64MB=0x2
-PCI_PCIEXBAR_REG_LENGTH_512MB=0x3
-PCI_PCIEXBAR_REG_LENGTH_1024MB=0x4
-PCI_PCIEXBAR_REG_LENGTH_2048MB=0x5
-PCI_PCIEXBAR_REG_LENGTH_4096MB=0x6
-PCI_PCIEBAR_REG_MASK=0x7FFC000000
-
-
-
[docs]classMMIO(hal_base.HALBase):
-
- def__init__(self,cs):
- super(MMIO,self).__init__(cs)
- self.cached_bar_addresses={}
- self.cache_bar_addresses_resolution=False
-
- ###########################################################################
- # Access to MMIO BAR defined by configuration files (chipsec/cfg/*.py)
- ###########################################################################
- #
- # To add your own MMIO bar:
- # 1. Add new MMIO BAR id (any)
- # 2. Write a function get_yourBAR_base_address() with no args that
- # returns base address of new bar
- # 3. Add a pointer to this function to MMIO_BAR_base map
- # 4. Don't touch read/write_MMIO_reg functions ;)
- #
- ###########################################################################
-
- #
- # Read MMIO register as an offset off of MMIO range base address
- #
-
-
-
- ###############################################################################
- # Access to MMIO BAR defined by XML configuration files (chipsec/cfg/*.xml)
- ###############################################################################
-
- #
- # Check if MMIO BAR with bar_name has been defined in XML config
- # Use this function to fall-back to hardcoded config in case XML config is not available
- #
-
-
[docs]defis_MMIO_BAR_defined(self,bar_name:str)->bool:
- is_bar_defined=False
- try:
- _bar=self.cs.Cfg.MMIO_BARS[bar_name]
- if_barisnotNone:
- if'register'in_bar:
- is_bar_defined=self.cs.is_register_defined(_bar['register'])
- elif('bus'in_bar)and('dev'in_bar)and('fun'in_bar)and('reg'in_bar):
- # old definition
- is_bar_defined=True
- exceptKeyError:
- pass
-
- ifnotis_bar_defined:
- ifself.logger.HAL:
- self.logger.log_warning(f"'{bar_name}' MMIO BAR definition not found/correct in XML config")
- returnis_bar_defined
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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
-#
-
-
-"""
-Access to message bus (IOSF sideband) interface registers on Intel SoCs
-
-References:
-
-- Intel(R) Atom(TM) Processor D2000 and N2000 Series Datasheet, Volume 2, July 2012, Revision 003
- http://www.intel.com/content/dam/doc/datasheet/atom-d2000-n2000-vol-2-datasheet.pdf (section 1.10.2)
-
-usage:
- >>> msgbus_reg_read( port, register )
- >>> msgbus_reg_write( port, register, data )
- >>> msgbus_read_message( port, register, opcode )
- >>> msgbus_write_message( port, register, opcode, data )
- >>> msgbus_send_message( port, register, opcode, data )
-"""
-
-fromtypingimportOptional
-fromchipsec.halimporthal_base
-fromchipsec.exceptionsimportRegisterNotFoundError
-
-
-#
-# IOSF Message bus message opcodes
-# Reference: http://lxr.free-electrons.com/source/arch/x86/include/asm/iosf_mbi.h
-#
-
-
-#
-# IOSF Message bus unit ports
-# Reference: http://lxr.free-electrons.com/source/arch/x86/include/asm/iosf_mbi.h
-# @TODO: move these to per-platform XML config?
-#
-
-
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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
-#
-
-
-"""
-Access to CPU resources (for each CPU thread): Model Specific Registers (MSR), IDT/GDT
-
-usage:
- >>> read_msr( 0x8B )
- >>> write_msr( 0x79, 0x12345678 )
- >>> get_IDTR( 0 )
- >>> get_GDTR( 0 )
- >>> dump_Descriptor_Table( 0, DESCRIPTOR_TABLE_CODE_IDTR )
- >>> IDT( 0 )
- >>> GDT( 0 )
- >>> IDT_all()
- >>> GDT_all()
-"""
-
-fromtypingimportDict,Tuple,Optional
-fromchipsec.loggerimportlogger,print_buffer_bytes
-
-
-DESCRIPTOR_TABLE_CODE_IDTR=0
-DESCRIPTOR_TABLE_CODE_GDTR=1
-DESCRIPTOR_TABLE_CODE_LDTR=2
-
-MTRR_MEMTYPE_UC=0x0
-MTRR_MEMTYPE_WC=0x1
-MTRR_MEMTYPE_WT=0x4
-MTRR_MEMTYPE_WP=0x5
-MTRR_MEMTYPE_WB=0x6
-MemType:Dict[int,str]={
- MTRR_MEMTYPE_UC:'Uncacheable (UC)',
- MTRR_MEMTYPE_WC:'Write Combining (WC)',
- MTRR_MEMTYPE_WT:'Write-through (WT)',
- MTRR_MEMTYPE_WP:'Write-protected (WP)',
- MTRR_MEMTYPE_WB:'Writeback (WB)'
-}
-
-
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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
-#
-
-"""
-x64/IA-64 Paging functionality including x86 page tables, Extended Page Tables (EPT) and VT-d page tables
-"""
-
-importsys
-importstruct
-fromtypingimportDict,List,Optional,Any
-importchipsec.defines
-fromchipsec.loggerimportlogger
-fromchipsec.exceptionsimportInvalidMemoryAddress
-
-ADDR_MASK=chipsec.defines.MASK_64b
-MAXPHYADDR=0x000FFFFFFFFFF000
-
-SIZE_4KB=chipsec.defines.BOUNDARY_4KB
-SIZE_2MB=chipsec.defines.BOUNDARY_2MB
-SIZE_1GB=chipsec.defines.BOUNDARY_1GB
-ADDR_4KB=0xFFFFFFFFFFFFF000&MAXPHYADDR
-ADDR_2MB=0xFFFFFFFFFFE00000&MAXPHYADDR
-ADDR_1GB=0xFFFFFFFFC0000000&MAXPHYADDR
-
-TranslationType=Dict[int,Dict[str,Any]]# TODO: TypedDict (PEP589)
-
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-2022, 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
-#
-
-"""
-Access to of PCI/PCIe device hierarchy
-- enumerating PCI/PCIe devices
-- read/write access to PCI configuration headers/registers
-- enumerating PCI expansion (option) ROMs
-- identifying PCI/PCIe devices MMIO and I/O ranges (BARs)
-
-usage:
- >>> self.cs.pci.read_byte( 0, 0, 0, 0x88 )
- >>> self.cs.pci.write_byte( 0, 0, 0, 0x88, 0x1A )
- >>> self.cs.pci.enumerate_devices()
- >>> self.cs.pci.enumerate_xroms()
- >>> self.cs.pci.find_XROM( 2, 0, 0, True, True, 0xFED00000 )
- >>> self.cs.pci.get_device_bars( 2, 0, 0 )
- >>> self.cs.pci.get_DIDVID( 2, 0, 0 )
- >>> self.cs.pci.is_enabled( 2, 0, 0 )
-"""
-
-importstruct
-fromcollectionsimportnamedtuple
-importitertools
-fromtypingimportList,Tuple,Optional
-fromchipsec.loggerimportlogger,pretty_print_hex_buffer
-fromchipsec.fileimportwrite_file
-fromchipsec.hal.pcidbimportVENDORS,DEVICES
-fromchipsec.exceptionsimportOsHelperError
-fromchipsec.definesimportis_all_ones,MASK_16b,MASK_32b,MASK_64b,BOUNDARY_4KB
-
-#
-# PCI configuration header registers
-#
-
-# Common (type 0/1) registers
-PCI_HDR_VID_OFF=0x0
-PCI_HDR_DID_OFF=0x2
-PCI_HDR_CMD_OFF=0x4
-PCI_HDR_STS_OFF=0x6
-PCI_HDR_RID_OFF=0x8
-PCI_HDR_CLSCODE_OFF=0x9
-PCI_HDR_PI_OFF=0x9
-PCI_HDR_SUB_CLS_OFF=0xA
-PCI_HDR_CLS_OFF=0xB
-PCI_HDR_CLSIZE_OFF=0xC
-PCI_HDR_MLT_OFF=0xD
-PCI_HDR_TYPE_OFF=0xE
-PCI_HDR_BIST_OFF=0xF
-PCI_HDR_CAP_OFF=0x34
-PCI_HDR_INTRLN_OFF=0x3C
-PCI_HDR_INTRPIN_OFF=0x3D
-PCI_HDR_BAR0_LO_OFF=0x10
-PCI_HDR_BAR0_HI_OFF=0x14
-
-# PCIe BAR register fields
-PCI_HDR_BAR_CFGBITS_MASK=0xF
-
-PCI_HDR_BAR_IOMMIO_MASK=0x1
-PCI_HDR_BAR_IOMMIO_MMIO=0
-PCI_HDR_BAR_IOMMIO_IO=1
-
-PCI_HDR_BAR_TYPE_MASK=(0x3<<1)
-PCI_HDR_BAR_TYPE_SHIFT=1
-PCI_HDR_BAR_TYPE_64B=2
-PCI_HDR_BAR_TYPE_1MB=1
-PCI_HDR_BAR_TYPE_32B=0
-
-PCI_HDR_BAR_BASE_MASK_MMIO64=0xFFFFFFFFFFFFFFF0
-PCI_HDR_BAR_BASE_MASK_MMIO=0xFFFFFFF0
-PCI_HDR_BAR_BASE_MASK_IO=0xFFFC
-
-# Type 0 specific registers
-PCI_HDR_TYPE0_BAR1_LO_OFF=0x18
-PCI_HDR_TYPE0_BAR1_HI_OFF=0x1C
-PCI_HDR_TYPE0_BAR2_LO_OFF=0x20
-PCI_HDR_TYPE0_BAR2_HI_OFF=0x24
-PCI_HDR_TYPE0_XROM_BAR_OFF=0x30
-
-# Type 1 specific registers
-PCI_HDR_TYPE1_XROM_BAR_OFF=0x38
-
-# Field defines
-
-PCI_HDR_CMD_MS_MASK=0x2
-
-PCI_HDR_TYPE_TYPE_MASK=0x7F
-PCI_HDR_TYPE_MF_MASK=0x80
-
-PCI_TYPE0=0x0
-PCI_TYPE1=0x1
-
-PCI_HDR_XROM_BAR_EN_MASK=0x00000001
-PCI_HDR_XROM_BAR_BASE_MASK=0xFFFFF000
-
-PCI_HDR_BAR_STEP=0x4
-
-
-#
-# Generic/standard PCI Expansion (Option) ROM
-#
-
-XROM_SIGNATURE=0xAA55
-PCI_XROM_HEADER_FMT='<H22sH'
-PCI_XROM_HEADER_SIZE=struct.calcsize(PCI_XROM_HEADER_FMT)
-
-
-
-
- #
- # Calculates actual size of MMIO BAR range
-
[docs]defcalc_bar_size(self,bus:int,dev:int,fun:int,off:int,is64:bool,isMMIO:bool)->int:
- self.logger.log_hal(f'calc_bar_size {bus}:{dev}.{fun} offset{off}')
- # Read the original value of the register
- orig_regL=self.read_dword(bus,dev,fun,off)
- self.logger.log_hal(f'orig_regL: {orig_regL:X}')
- ifis64:
- orig_regH=self.read_dword(bus,dev,fun,off+PCI_HDR_BAR_STEP)
- self.logger.log_hal(f'orig_regH: {orig_regH:X}')
- # Write all 1's to the register
- self.write_dword(bus,dev,fun,off+PCI_HDR_BAR_STEP,MASK_32b)
- ifis64:
- self.write_dword(bus,dev,fun,off,MASK_32b)
- # Read the register back
- regL=self.read_dword(bus,dev,fun,off)
- self.logger.log_hal(f'regL: {regL:X}')
- ifis64:
- regH=self.read_dword(bus,dev,fun,off+PCI_HDR_BAR_STEP)
- self.logger.log_hal(f'regH: {regH:X}')
- # Write original value back to register
- self.write_dword(bus,dev,fun,off,orig_regL)
- ifis64:
- self.write_dword(bus,dev,fun,off+PCI_HDR_BAR_STEP,orig_regH)
- # Calculate Sizing
- ifisMMIOandis64:
- reg=regL|(regH<<32)
- orig_reg=orig_regL|(orig_regH<<32)
- iforig_reg==reg:
- size=BOUNDARY_4KB
- else:
- size=(~(reg&PCI_HDR_BAR_BASE_MASK_MMIO64)&MASK_64b)+1
- elifisMMIO:
- ifregL==orig_regL:
- size=BOUNDARY_4KB
- else:
- size=(~(regL&PCI_HDR_BAR_BASE_MASK_MMIO)&MASK_32b)+1
- else:
- ifregL==orig_regL:
- size=0x100
- else:
- size=(~(regL&PCI_HDR_BAR_BASE_MASK_IO)&MASK_16b)+1
- returnsize
-
- # Returns all I/O and MMIO BARs defined in the PCIe header of the device
- # Returns array of elements in format (BAR_address, isMMIO, is64bit, BAR_reg_offset, BAR_reg_value)
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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
-#
-
-"""
-Access to physical memory
-
-usage:
- >>> read_physical_mem( 0xf0000, 0x100 )
- >>> write_physical_mem( 0xf0000, 0x100, buffer )
- >>> write_physical_mem_dowrd( 0xf0000, 0xdeadbeef )
- >>> read_physical_mem_dowrd( 0xfed40000 )
-"""
-
-fromstructimportunpack,pack
-fromtypingimportTuple,Optional
-fromchipsec.hal.hal_baseimportHALBase
-fromchipsec.loggerimportprint_buffer_bytes
-
-
-
[docs]classMemory(HALBase):
- def__init__(self,cs):
- super(Memory,self).__init__(cs)
- self.helper=cs.helper
-
- ####################################################################################
- #
- # Physical memory API using 64b Physical Address
- # (Same functions as below just using 64b PA instead of High and Low 32b parts of PA)
- #
- ####################################################################################
-
- # Reading physical memory
-
-
[docs]defread_physical_mem_qword(self,phys_address:int)->int:
- out_buf=self.read_physical_mem(phys_address,8)
- value=unpack('=Q',out_buf)[0]
- self.logger.log_hal(f'[mem] qword at PA = 0x{phys_address:016X}: 0x{value:016X}')
- returnvalue
-
-
[docs]defread_physical_mem_dword(self,phys_address:int)->int:
- out_buf=self.read_physical_mem(phys_address,4)
- value=unpack('=I',out_buf)[0]
- self.logger.log_hal(f'[mem] dword at PA = 0x{phys_address:016X}: 0x{value:08X}')
- returnvalue
-
-
[docs]defread_physical_mem_word(self,phys_address:int)->int:
- out_buf=self.read_physical_mem(phys_address,2)
- value=unpack('=H',out_buf)[0]
- self.logger.log_hal(f'[mem] word at PA = 0x{phys_address:016X}: 0x{value:04X}')
- returnvalue
-
-
[docs]defread_physical_mem_byte(self,phys_address:int)->int:
- out_buf=self.read_physical_mem(phys_address,1)
- value=unpack('=B',out_buf)[0]
- self.logger.log_hal(f'[mem] byte at PA = 0x{phys_address:016X}: 0x{value:02X}')
- returnvalue
-
- # Writing physical memory
-
-
[docs]defwrite_physical_mem(self,phys_address:int,length:int,buf:bytes)->int:
- ifself.logger.HAL:
- self.logger.log(f'[mem] buffer len = 0x{length:X} to PA = 0x{phys_address:016X}')
- print_buffer_bytes(buf)
- returnself.helper.write_phys_mem(phys_address,length,buf)
-
-
[docs]defwrite_physical_mem_dword(self,phys_address:int,dword_value:int)->int:
- self.logger.log_hal(f'[mem] dword to PA = 0x{phys_address:016X} <- 0x{dword_value:08X}')
- returnself.write_physical_mem(phys_address,4,pack('I',dword_value))
-
-
[docs]defwrite_physical_mem_word(self,phys_address:int,word_value:int)->int:
- self.logger.log_hal(f'[mem] word to PA = 0x{phys_address:016X} <- 0x{word_value:04X}')
- returnself.write_physical_mem(phys_address,2,pack('H',word_value))
-
-
[docs]defwrite_physical_mem_byte(self,phys_address:int,byte_value:int)->int:
- self.logger.log_hal(f'[mem] byte to PA = 0x{phys_address:016X} <- 0x{byte_value:02X}')
- returnself.write_physical_mem(phys_address,1,pack('B',byte_value))
-
- # Allocate physical memory buffer
-
-
[docs]defalloc_physical_mem(self,length:int,max_phys_address:int=0xFFFFFFFFFFFFFFFF)->Tuple[int,int]:
- (va,pa)=self.helper.alloc_phys_mem(length,max_phys_address)
- self.logger.log_hal(f'[mem] Allocated: PA = 0x{pa:016X}, VA = 0x{va:016X}')
- return(va,pa)
-
-
[docs]defva2pa(self,va:int)->Optional[int]:
- (pa,error_code)=self.helper.va2pa(va)
- iferror_code:
- self.logger.log_hal(f'[mem] Looks like VA (0x{va:016X}) not mapped')
- returnNone
- self.logger.log_hal(f'[mem] VA (0x{va:016X}) -> PA (0x{pa:016X})')
- returnpa
-
- # Map physical address to virtual
-
-
[docs]defmap_io_space(self,pa:int,length:int,cache_type:int)->int:
- va=self.helper.map_io_space(pa,length,cache_type)
- self.logger.log_hal(f'[mem] Mapped: PA = 0x{pa:016X}, VA = 0x{va:016X}')
- returnva
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2019-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
-#
-
-"""
-HAL component providing access to and decoding of SMBIOS structures
-"""
-
-importstruct
-fromcollectionsimportnamedtuple
-fromtypingimportDict,List,Optional,Tuple,Any,Union,Type
-fromchipsec.definesimportBOUNDARY_1MB,bytestostring
-fromchipsec.halimporthal_base,uefi
-fromchipsec.loggerimportlogger
-
-SCAN_LOW_LIMIT=0xF0000
-SCAN_SIZE=0x10000
-
-SMBIOS_2_x_SIG=b"_SM_"
-SMBIOS_2_x_ENTRY_SIZE=0x1F
-SMBIOS_2_x_ENTRY_SIZE_OLD=0x1E
-SMBIOS_2_x_MAJOR_VER=0x02
-SMBIOS_2_x_INT_SIG=b"_DMI_"
-SMBIOS_2_x_GUID="EB9D2D31-2D88-11D3-9A16-0090273FC14D"
-SMBIOS_2_x_ENTRY_POINT_FMT="=4sBBBBHB5B5sBHIHB"
-SMBIOS_2_x_ENTRY_POINT_SIZE=struct.calcsize(SMBIOS_2_x_ENTRY_POINT_FMT)
-
-
-
[docs]classSMBIOS(hal_base.HALBase):
- def__init__(self,cs):
- super(SMBIOS,self).__init__(cs)
- self.uefi=uefi.UEFI(cs)
- self.smbios_2_guid_found=False
- self.smbios_2_pa=None
- self.smbios_2_ep=None
- self.smbios_2_data=None
- self.smbios_3_guid_found=False
- self.smbios_3_pa=None
- self.smbios_3_ep=None
- self.smbios_3_data=None
-
- def__get_raw_struct(self,table:bytes,start_offset:int)->Tuple[Optional[bytes],Optional[int]]:
- """
- Returns a tuple including the raw data and the offset to the next entry. This allows the function
- to be called multiple times to process all the entries in a table.
-
- Return Value:
- (raw_data, next_offset)
-
- Error/End:
- (None, None)
- """
- # Check for end of table and remaining size to parse
- iftableisNone:
- logger().log_hal('- Invalid table')
- return(None,None)
- table_len=len(table)
- logger().log_hal(f'Start Offset: 0x{start_offset:04X}, Table Size: 0x{table_len:04X}')
- ifstart_offset>=table_len:
- logger().log_hal(f'- Bad table length (table_len): 0x{table_len:04X}')
- return(None,None)
- size_left=len(table[start_offset:])
- ifsize_left<SMBIOS_STRUCT_HEADER_SIZE:
- logger().log_hal(f'- Table too small (size_left): 0x{size_left:04X}')
- return(None,None)
-
- # Read the header to determine structure fixed size
- try:
- header=SMBIOS_STRUCT_HEADER(*struct.unpack_from(SMBIOS_STRUCT_HEADER_FMT,
- table[start_offset:start_offset+SMBIOS_STRUCT_HEADER_SIZE]))
- except:
- logger().log_hal('- Unable to unpack data')
- return(None,None)
- str_offset=start_offset+header.Length
- ifstr_offset+SMBIOS_STRUCT_TERM_SIZE>=table_len:
- logger().log_hal(f'- Not enough space for termination (str_offset): 0x{str_offset:04X}')
- return(None,None)
-
- # Process any remaining content (strings)
- logger().log_hal(f'String start offset: 0x{str_offset:04X}')
- tmp_offset=str_offset
- while(tmp_offset+SMBIOS_STRUCT_TERM_SIZE<table_len):
- (value,)=struct.unpack_from(SMBIOS_STRUCT_TERM_FMT,table[tmp_offset:tmp_offset+SMBIOS_STRUCT_TERM_SIZE])
- ifvalue==SMBIOS_STRUCT_TERM_VAL:
- logger().log_hal('+ Found structure termination')
- break
- tmp_offset+=1
- iftmp_offset>=table_len:
- logger().log_hal('- End of table reached')
- return(None,None)
- tmp_offset+=SMBIOS_STRUCT_TERM_SIZE
-
- logger().log_hal(f'Structure Size: 0x{tmp_offset-start_offset:04X}')
- return(table[start_offset:tmp_offset],tmp_offset)
-
- def__validate_ep_2_values(self,pa:int)->Optional[SMBIOS_2_x_ENTRY_POINT]:
- # Force a second read of memory so we don't have to worry about it falling outside the
- # original buffer.
- try:
- logger().log_hal(f'Validating 32bit SMBIOS header @ 0x{pa:08X}')
- mem_buffer=self.cs.mem.read_physical_mem(pa,SMBIOS_2_x_ENTRY_POINT_SIZE)
- ep_data=SMBIOS_2_x_ENTRY_POINT(*struct.unpack_from(SMBIOS_2_x_ENTRY_POINT_FMT,mem_buffer))
- except:
- logger().log_hal('- Memory read failed')
- returnNone
- ifep_data.Anchor!=SMBIOS_2_x_SIG:
- logger().log_hal('- Invalid signature')
- returnNone
- ifnot(ep_data.EntryLen==SMBIOS_2_x_ENTRY_SIZEorep_data.EntryLen==SMBIOS_2_x_ENTRY_SIZE_OLD):
- logger().log_hal('- Invalid structure size')
- returnNone
- ifep_data.IntAnchor!=SMBIOS_2_x_INT_SIG:
- logger().log_hal('- Invalid intermediate signature')
- returnNone
- if(ep_data.TableAddr==0)or(ep_data.TableLen==0):
- logger().log_hal('- Invalid table address or length')
- returnNone
- returnep_data
-
- def__validate_ep_3_values(self,pa:int)->Optional[SMBIOS_3_x_ENTRY_POINT]:
- # Force a second read of memory so we don't have to worry about it falling outside the
- # original buffer.
- try:
- logger().log_hal(f'Validating 64bit SMBIOS header @ 0x{pa:08X}')
- mem_buffer=self.cs.mem.read_physical_mem(pa,SMBIOS_3_x_ENTRY_POINT_SIZE)
- ep_data=SMBIOS_3_x_ENTRY_POINT(*struct.unpack_from(SMBIOS_3_x_ENTRY_POINT_FMT,mem_buffer))
- except:
- logger().log_hal('- Memory read failed')
- returnNone
- ifep_data.Anchor!=SMBIOS_3_x_SIG:
- logger().log_hal('- Invalid signature')
- returnNone
- ifnot(ep_data.EntryLen==SMBIOS_3_x_ENTRY_SIZE):
- logger().log_hal('- Invalid structure size')
- returnNone
- ifep_data.MaxSize==0orep_data.TableAddr==0:
- logger().log_hal('- Invalid table address or maximum size')
- returnNone
- returnep_data
-
-
[docs]deffind_smbios_table(self)->bool:
- # Handle the case were we already found the tables
- ifself.smbios_2_episnotNoneorself.smbios_3_episnotNone:
- returnTrue
-
- # Initialize search parameters
- entries_to_find=entries_found=0
-
- # Fist get the configuration table using the UEFI HAL. You may not be able to use the addresses
- # in the table because in some cases they have been converted to a VA and are not mapped.
- logger().log_hal('Checking UEFI Configuration Table for SMBIOS entry')
- (ect_found,_,ect,_)=self.uefi.find_EFI_Configuration_Table()
- ifect_foundand(ectisnotNone):
- logger().log_hal(str(ect))
- ifSMBIOS_2_x_GUIDinect.VendorTables:
- logger().log_hal('+ Found 32bit SMBIOS entry')
- logger().log_hal(f'+ Potential 2.x table address: 0x{ect.VendorTables[SMBIOS_2_x_GUID]:016X}')
- self.smbios_2_guid_found=True
- entries_to_find+=1
- ifSMBIOS_3_x_GUIDinect.VendorTables:
- logger().log_hal('+ Found 64bit SMBIOS entry')
- logger().log_hal(f'+ Potential 3.x table address: 0x{ect.VendorTables[SMBIOS_3_x_GUID]:016X}')
- self.smbios_3_guid_found=True
- entries_to_find+=1
-
- # Determine regions to scan
- ifself.smbios_2_guid_foundorself.smbios_3_guid_found:
- (smm_base,_,_)=self.cs.cpu.get_SMRAM()
- pa=smm_base-SCAN_SIZE
- else:
- entries_to_find=2
- pa=BOUNDARY_1MB-SCAN_SIZE
-
- # Scan memory for the signature
- logger().log_hal(f'Scanning memory for {entries_to_find:d} signature(s)')
- while(pa>=SCAN_LOW_LIMIT):
- mem_buffer=self.cs.mem.read_physical_mem(pa,SCAN_SIZE)
- sig_pa=mem_buffer.find(SMBIOS_2_x_SIG)+pa
- ifsig_pa>=paandself.smbios_2_paisNone:
- logger().log_hal(f'+ Found SMBIOS 2.x signature @ 0x{sig_pa:08X}')
- self.smbios_2_ep=self.__validate_ep_2_values(sig_pa)
- ifself.smbios_2_episnotNone:
- logger().log_hal('+ Verified SMBIOS 2.x Entry Point structure')
- self.smbios_2_pa=sig_pa
- entries_found+=1
- sig_pa=mem_buffer.find(SMBIOS_3_x_SIG)+pa
- ifsig_pa>=paandself.smbios_3_paisNone:
- logger().log_hal(f'+ Found SMBIOS 3.x signature @ 0x{sig_pa:08X}')
- self.smbios_3_ep=self.__validate_ep_3_values(sig_pa)
- ifself.smbios_3_episnotNone:
- logger().log_hal('+ Verified SMBIOS 3.x Entry Point structure')
- self.smbios_3_pa=sig_pa
- entries_found+=1
- ifentries_found>=entries_to_find:
- break
- pa-=SCAN_SIZE
-
- # Check to see if we thing we found the structure
- ifself.smbios_2_paisNoneandself.smbios_3_paisNone:
- logger().log_hal('- Unable to find SMBIOS tables')
- returnFalse
-
- # Read the raw data regions
- logger().log_hal('Reading SMBIOS data tables:')
- ifself.smbios_2_episnotNoneandself.smbios_2_ep.TableAddr!=0andself.smbios_2_ep.TableLen!=0:
- self.smbios_2_data=self.cs.mem.read_physical_mem(self.smbios_2_ep.TableAddr,self.smbios_2_ep.TableLen)
- ifself.smbios_2_dataisNone:
- logger().log_hal('- Failed to read 32bit SMBIOS data')
- ifself.smbios_3_episnotNoneandself.smbios_3_ep.TableAddr!=0andself.smbios_3_ep.MaxSize!=0:
- self.smbios_3_data=self.cs.mem.read_physical_mem(self.smbios_3_ep.TableAddr,self.smbios_3_ep.MaxSize)
- ifself.smbios_3_dataisNone:
- logger().log_hal('- Failed to read 64bit SMBIOS data')
-
- returnTrue
-
-
[docs]defget_raw_structs(self,struct_type:Optional[int],force_32bit:bool):
- """
- Returns a list of raw data blobs for each SMBIOS structure. The default is to process the 64bit
- entries if available unless specifically specified.
-
- Error:
- None
- """
- ret_val=[]
-
- ifself.smbios_3_dataisnotNoneandnotforce_32bit:
- logger().log_hal('Using 64bit SMBIOS table')
- table=self.smbios_3_data
- elifself.smbios_2_dataisnotNone:
- logger().log_hal('Using 32bit SMBIOS table')
- table=self.smbios_2_data
- else:
- logger().log_hal('- No SMBIOS data available')
- returnNone
-
- logger().log_hal('Getting SMBIOS structures...')
- raw_data,next_offset=self.__get_raw_struct(table,0)
- while(next_offsetisnotNone)and(raw_dataisnotNone):
- ifstruct_typeisNone:
- ret_val.append(raw_data)
- else:
- header=SMBIOS_STRUCT_HEADER(*struct.unpack_from(SMBIOS_STRUCT_HEADER_FMT,raw_data[:SMBIOS_STRUCT_HEADER_SIZE]))
- ifheaderisnotNoneandheader.Type==struct_type:
- ret_val.append(raw_data)
- raw_data,next_offset=self.__get_raw_struct(table,next_offset)
-
- returnret_val
-
-
[docs]defget_header(self,raw_data:bytes)->Optional[SMBIOS_STRUCT_HEADER]:
- logger().log_hal('Getting generic SMBIOS header information')
- ifraw_dataisNone:
- logger().log_hal('- Raw data pointer is None')
- returnNone
- iflen(raw_data)<SMBIOS_STRUCT_HEADER_SIZE:
- logger().log_hal('- Raw data too small for header information')
- returnNone
-
- try:
- header=SMBIOS_STRUCT_HEADER(*struct.unpack_from(SMBIOS_STRUCT_HEADER_FMT,raw_data[:SMBIOS_STRUCT_HEADER_SIZE]))
- except:
- logger().log_hal('- Failed to extract information from raw data')
- returnNone
-
- returnheader
-
-
[docs]defget_string_list(self,raw_data:bytes)->Optional[List[str]]:
- ret_val=[]
-
- logger().log_hal('Getting strings from structure')
- raw_data_size=len(raw_data)
- header=self.get_header(raw_data)
- ifheaderisNone:
- returnNone
- ifheader.Length+SMBIOS_STRUCT_TERM_SIZE>raw_data_size:
- logger().log_hal('- Data buffer too small for structure')
- returnNone
- ifheader.Length+SMBIOS_STRUCT_TERM_SIZE==raw_data_size:
- logger().log_hal('+ No strings in this structure')
- returnret_val
-
- index=0
- tmp_offset=header.Length
- whiletmp_offset+index+1<raw_data_size:
- (value,)=struct.unpack_from('=B',raw_data[tmp_offset+index:])
- ifvalue==0:
- logger().log_hal(f'+ Unpacking string of size {index:d}')
- (string,)=struct.unpack_from(f'={index:d}s',raw_data[tmp_offset:])
- string=bytestostring(string)
- logger().log_hal(f'+ Found: {string:s}')
- ret_val.append(string)
- tmp_offset+=index+1
- index=0
- continue
- index+=1
-
- logger().log_hal(f'+ Found {len(ret_val):d} strings')
- returnret_val
-
-
[docs]defget_decoded_structs(self,struct_type:Optional[int]=None,force_32bit:bool=False)->Optional[List[Type[SmbiosInfo]]]:
- ret_val=[]
-
- # Determine if the structure exists in the table
- logger().log_hal('Getting decoded SMBIOS structures')
- structs=self.get_raw_structs(struct_type,force_32bit)
- ifstructsisNone:
- returnNone
-
- # Process all the entries
- fordatainstructs:
- # Get the structures header information so we can determine the correct decode method
- header=self.get_header(data)
- ifheaderisNone:
- logger().log_hal('- Could not decode header')
- continue
- ifheader.Typenotinstruct_decode_tree:
- logger().log_hal(f'- Structure {header.Type:d} not in decode list')
- continue
-
- # Unpack the structure and then get the strings
- tmp_decode=struct_decode_tree[header.Type]
- try:
- decode_data=struct.unpack_from(tmp_decode['format'],data)
- except:
- logger().log_hal('- Could not decode structure')
- continue
- ifdecode_dataisNone:
- logger().log_hal('- No structure data was decoded')
- continue
- strings=self.get_string_list(data)
- ifstringsisnotNone:
- decode_data=decode_data+(strings,)
-
- # Create the actual object
- try:
- decode_object=tmp_decode['class'](*decode_data)
- except:
- logger().log_hal('- Failed to create structure')
- continue
- ret_val.append(decode_object)
-
- returnret_val
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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: Platform Hardware Security Assessment Framework
-#
-# -------------------------------------------------------------------------------
-
-"""
-Access to SMBus Controller
-"""
-fromtypingimportList
-fromchipsec.halimportiobar,hal_base
-fromchipsec.exceptionsimportIOBARNotFoundError,RegisterNotFoundError
-
-SMBUS_COMMAND_QUICK=0
-SMBUS_COMMAND_BYTE=1
-SMBUS_COMMAND_BYTE_DATA=2
-SMBUS_COMMAND_WORD_DATA=3
-SMBUS_COMMAND_PROCESS_CALL=4
-SMBUS_COMMAND_BLOCK=5
-SMBUS_COMMAND_I2C_READ=6
-SMBUS_COMMAND_BLOCK_PROCESS=7
-
-SMBUS_POLL_COUNT=1000
-
-SMBUS_COMMAND_WRITE=0
-SMBUS_COMMAND_READ=1
-
-
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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
-#
-
-"""
-Access to Memory (DRAM) Serial Presence Detect (SPD) EEPROM
-
-References:
-
-http://www.jedec.org/sites/default/files/docs/4_01_02R19.pdf
-http://www.jedec.org/sites/default/files/docs/4_01_02_10R17.pdf
-http://www.jedec.org/sites/default/files/docs/4_01_02_11R24.pdf
-http://www.jedec.org/sites/default/files/docs/4_01_02_12R23A.pdf
-https://www.simmtester.com/News/PublicationArticle/184
-https://www.simmtester.com/News/PublicationArticle/153
-https://www.simmtester.com/News/PublicationArticle/101
-http://en.wikipedia.org/wiki/Serial_presence_detect
-"""
-
-importstruct
-fromtypingimportAny,List
-fromcollectionsimportnamedtuple
-
-fromchipsec.loggerimportlogger,print_buffer_bytes
-
-SPD_SMBUS_ADDRESS=0xA0# A2, A4, A6, A8, AA, AC, AE
-SPD_SMBUS_ADDRESS_DIMM0=SPD_SMBUS_ADDRESS
-SPD_SMBUS_ADDRESS_DIMM1=SPD_SMBUS_ADDRESS+0x2
-SPD_SMBUS_ADDRESS_DIMM2=SPD_SMBUS_ADDRESS+0x4
-SPD_SMBUS_ADDRESS_DIMM3=SPD_SMBUS_ADDRESS+0x6
-SPD_SMBUS_ADDRESS_DIMM4=SPD_SMBUS_ADDRESS+0x8
-SPD_SMBUS_ADDRESS_DIMM5=SPD_SMBUS_ADDRESS+0xA
-SPD_SMBUS_ADDRESS_DIMM6=SPD_SMBUS_ADDRESS+0xC
-SPD_SMBUS_ADDRESS_DIMM7=SPD_SMBUS_ADDRESS+0xE
-MAX_DIMM_SPD_COUNT=8
-
-SPD_DIMMS={}
-foriinrange(MAX_DIMM_SPD_COUNT):
- SPD_DIMMS[SPD_SMBUS_ADDRESS+i*2]=f'DIMM{i:d}'
-
-SPD_DIMM_ADDRESSES={}
-foriinrange(MAX_DIMM_SPD_COUNT):
- SPD_DIMM_ADDRESSES[f'DIMM{i:d}']=SPD_SMBUS_ADDRESS+i*2
-
-###############################################################################
-#
-# SPD Decode
-#
-# References:
-# http://www.jedec.org/sites/default/files/docs/4_01_02R19.pdf
-# http://www.jedec.org/sites/default/files/docs/4_01_02_10R17.pdf
-# http://www.jedec.org/sites/default/files/docs/4_01_02_11R24.pdf
-# http://www.jedec.org/sites/default/files/docs/4_01_02_12R23A.pdf
-# http://www.simmtester.com/page/news/showpubnews.asp?num=184
-# http://www.simmtester.com/page/news/showpubnews.asp?num=153
-# http://www.simmtester.com/page/news/showpubnews.asp?num=101
-# http://en.wikipedia.org/wiki/Serial_presence_detect
-#
-# @TODO: add decode of other fields
-#
-###############################################################################
-
-#
-# DDR/DDR2/DDR3/DDR4 SPD
-#
-SPD_OFFSET_DRAM_DEVICE_TYPE=2# Fundamental Memory (DRAM) Type
-
-#
-# DDR SPD
-#
-SPD_OFFSET_DDR_SPD_BYTES=0
-SPD_OFFSET_DDR_SPD_SIZE=1
-SPD_OFFSET_DDR_ROW_ADDRESS_COUNT=3
-SPD_OFFSET_DDR_COL_ADDRESS_COUNT=4
-SPD_OFFSET_DDR_BANKDS_COUNT=5
-SPD_OFFSET_DDR_MODULE_WIDTH_LOW=6
-SPD_OFFSET_DDR_MODULE_WIDTH_HIGH=7
-SPD_OFFSET_DDR_VOLTAGE_IFACE_LEVEL=8
-SPD_OFFSET_DDR_CLOCK_FREQUENCY=9
-SPD_OFFSET_DDR_tAC=10
-SPD_OFFSET_DDR_DIMM_CONFIGURATION_TYPE=11
-SPD_OFFSET_DDR_REFRESH_RATE_TYPE=12
-SPD_OFFSET_DDR_PRIMARY_SDRAM_WIDTH=13
-SPD_OFFSET_DDR_ECC_SDRAM_WIDTH=14
-SPD_OFFSET_DDR_tCCD_MIN=15
-
-#
-# DDR3 SPD
-#
-SPD_OFFSET_DDR3_SPD_BYTES=0# SPD Bytes Written, Device Size, CRC coverage/range
-SPD_OFFSET_DDR3_SPD_REVISION=1# SPD Revision
-SPD_OFFSET_DDR3_MODULE_TYPE=3# Module Type
-SPD_OFFSET_DDR3_SDRAM_DENSITY_BANKS=4# SDRAM Density and Banks
-SPD_OFFSET_DDR3_SDRAM_ADDRESSING=5# SDRAM Addressing
-SPD_OFFSET_DDR3_VDD=6# Module Nominal Voltage, VDD
-SPD_OFFSET_DDR3_MODULE_ORGANIZATION=7# Module Organization
-SPD_OFFSET_DDR3_MEMORY_BUS_WIDTH_ECC=8# Module Memory Bus Width
-SPD_OFFSET_DDR3_FTB=9# Fine Time Base (FTB) Divident / Divisor
-SPD_OFFSET_DDR3_MTB_DIVIDENT=10# Medium Time Base (MTB) Divident
-SPD_OFFSET_DDR3_MTB_DIVISOR=11# Medium Time Base (MTB) Divisor
-SPD_OFFSET_DDR3_tCK_MIN=12# SDRAM Minimum Cycle Time (tCKmin)
-SPD_OFFSET_DDR3_RESERVED13=13# Reserved
-SPD_OFFSET_DDR3_CAS_LATENCY_LOW=14# CAS Latencies Supported, LSB
-SPD_OFFSET_DDR3_CAS_LATENCY_HIGH=15# CAS Latencies Supported, MSB
-
-#
-# DDR4 SPD
-#
-# Base Configuration and DRAM Parameters
-SPD_OFFSET_DDR4_SPD_BYTES=0# SPD Bytes Written, Device Size, CRC coverage/range
-SPD_OFFSET_DDR4_SPD_REVISION=1# SPD Revision
-SPD_OFFSET_DDR4_MODULE_TYPE=3# Module Type
-SPD_OFFSET_DDR4_SDRAM_DENSITY_BANKS=4# SDRAM Density and Banks
-SPD_OFFSET_DDR4_SDRAM_ADDRESSING=5# SDRAM Addressing
-SPD_OFFSET_DDR4_SDRAM_PACKAGE_TYPE=6# SDRAM Package Type
-SPD_OFFSET_DDR4_OPTIONAL_FEATURES=7# SDRAM Optional Features
-SPD_OFFSET_DDR4_THERMAL_AND_REFRESH=8# SDRAM Thermal and Refresh Options
-SPD_OFFSET_DDR4_OPTIONAL_FEATURES_1=9# Other Optional Features
-SPD_OFFSET_DDR4_RESERVED10=10# Reserved (must be 0x00)
-SPD_OFFSET_DDR4_VDD=11# Module Nominal Voltage, VDD
-SPD_OFFSET_DDR4_MODULE_ORGANIZATION=12# Module Organization
-SPD_OFFSET_DDR4_MEMORY_BUS_WIDTH_ECC=13# Module Memory Bus Width
-SPD_OFFSET_DDR4_MODULE_THERMAL_SENSOR=14# Module Thermal Sensor
-SPD_OFFSET_DDR4_MODULE_TYPE_EXTENDED=15# Extended Module Type
-
-
-#
-# Fundamental Memory Type
-# Ref: http://www.jedec.org/sites/default/files/docs/4_01_02_01R12.pdf
-#
-DRAM_DEVICE_TYPE_FPM_DRAM=0x1
-DRAM_DEVICE_TYPE_EDO=0x2
-DRAM_DEVICE_TYPE_PIPELINED_NIBBLE=0x3
-DRAM_DEVICE_TYPE_SDR=0x4
-DRAM_DEVICE_TYPE_MULTIPLEXED_ROM=0x5
-DRAM_DEVICE_TYPE_DDR=0x7
-DRAM_DEVICE_TYPE_DDR2=0x8
-DRAM_DEVICE_TYPE_DDR3=0x0B
-DRAM_DEVICE_TYPE_DDR4=0x0C
-DRAM_DEVICE_TYPE={
- DRAM_DEVICE_TYPE_FPM_DRAM:'Standard Fast Page Mode DRAM',
- DRAM_DEVICE_TYPE_EDO:'EDO DRAM',
- DRAM_DEVICE_TYPE_PIPELINED_NIBBLE:'Pipelined Nibble',
- DRAM_DEVICE_TYPE_SDR:'Sync DRAM (SDRAM)',
- DRAM_DEVICE_TYPE_MULTIPLEXED_ROM:'Multiplexed ROM',
- DRAM_DEVICE_TYPE_DDR:'DDR SDRAM',
- DRAM_DEVICE_TYPE_DDR2:'DDR2 SDRAM',
- DRAM_DEVICE_TYPE_DDR3:'DDR3 SDRAM',
- DRAM_DEVICE_TYPE_DDR4:'DDR4 SDRAM'
-}
-
-MODULE_TYPE_UNDEFINED=0x0
-MODULE_TYPE_RDIMM=0x1
-MODULE_TYPE_UDIMM=0x2
-MODULE_TYPE_SODIMM=0x3
-MODULE_TYPE_LRDIMM=0x4
-MODULE_TYPE={
- MODULE_TYPE_UNDEFINED:'Undefined',
- MODULE_TYPE_RDIMM:'Registered Long DIMM',
- MODULE_TYPE_UDIMM:'Unbuffered Long DIMM',
- MODULE_TYPE_SODIMM:'Small Outline DIMM',
- MODULE_TYPE_LRDIMM:'LR-DIMM'
-}
-
-SPD_REVISION_0_0=0x00
-SPD_REVISION_0_7=0x07
-SPD_REVISION_0_8=0x08
-SPD_REVISION_0_9=0x09
-SPD_REVISION_1_0=0x10
-SPD_REVISION_1_1=0x11
-SPD_REVISION_1_2=0x12
-SPD_REVISION_1_3=0x13
-
-
-
[docs]classSPD_DDR(namedtuple('SPD_DDR','SPDBytes TotalBytes DeviceType RowAddressCount')):
- __slots__=()
-
- def__str__(self)->str:
- returnf"""------------------------------------------------------------------
-SPD DDR
-------------------------------------------------------------------
-[0] Number of SPD bytes written: 0x{self.SPDBytes:02X}
-[1] Total number of bytes : 0x{self.TotalBytes:02X}
-[2] DRAM Memory Type : 0x{self.DeviceType:02X} ({dram_device_type_name(self.DeviceType)})
-[3] Number of Row Addresses : 0x{self.RowAddressCount:02X}
-------------------------------------------------------------------
-"""
-
-
-SPD_DDR2_FORMAT='=4B'
-
-
-
[docs]classSPD_DDR2(namedtuple('SPD_DDR2','SPDBytes TotalBytes DeviceType RowAddressCount')):
- __slots__=()
-
- def__str__(self)->str:
- returnf"""------------------------------------------------------------------
-SPD DDR2
-------------------------------------------------------------------
-[0] Number of SPD bytes written: 0x{self.SPDBytes:02X}
-[1] Total number of bytes : 0x{self.TotalBytes:02X}
-[2] DRAM Memory Type : 0x{self.DeviceType:02X} ({dram_device_type_name(self.DeviceType)})
-[3] Number of Row Addresses : 0x{self.RowAddressCount:02X}
-------------------------------------------------------------------
-"""
[docs]classSPD_DDR4(namedtuple('SPD_DDR4','SPDBytes Revision DeviceType ModuleType Density Addressing PackageType OptFeatures ThermalRefresh OptFeatures1 ReservedA VDD ModuleOrg BusWidthECC ThermSensor ModuleTypeExt')):
- __slots__=()
-
- def__str__(self)->str:
- returnf"""------------------------------------------------------------------
-SPD DDR4
-------------------------------------------------------------------
-Base Configuration and DRAM Parameters
-[0x00] SPD Bytes Written, Device Size, CRC: 0x{self.SPDBytes:02X}
-[0x01] SPD Revision : 0x{self.Revision:02X} ({SPD_REVISION(self.Revision)})
-[0x02] DRAM Memory Type : 0x{self.DeviceType:02X} ({dram_device_type_name(self.DeviceType)})
-[0x03] Module Type : 0x{self.ModuleType:02X} ({module_type_name(self.ModuleType)})
-[0x04] SDRAM Density and Banks : 0x{self.Density:02X}
-[0x05] SDRAM Addressing (Row/Column Bits) : 0x{self.Addressing:02X}
-[0x06] SDRAM Package Type : 0x{self.PackageType:02X}
-[0x07] SDRAM Optional Features : 0x{self.OptFeatures:02X}
-[0x08] SDRAM Thermal and Refresh Options : 0x{self.ThermalRefresh:02X}
-[0x09] Other Optional Features : 0x{self.OptFeatures1:02X}
-[0x0A] Reserved (== 0x00) : 0x{self.ReservedA:02X}
-[0x0B] Module Nominal Voltage, VDD : 0x{self.VDD:02X}
-[0x0C] Module Organization : 0x{self.ModuleOrg:02X}
-[0x0D] Module Memory Bus Width : 0x{self.BusWidthECC:02X}
-[0x0E] Module Thermal Sensor : 0x{self.ThermSensor:02X}
-[0x0F] Extended Module Type : 0x{self.ModuleTypeExt:02X}
-------------------------------------------------------------------
-"""
-
-
-###############################################################################
-#
-# Main SPD HAL component class
-#
-###############################################################################
-
-
[docs]defget_SPI_region(self,spi_region_id:int)->Tuple[int,int,int]:
- freg_name=SPI_REGION[spi_region_id]
- ifnotself.cs.is_register_defined(freg_name):
- return(0,0,0)
- freg=self.cs.read_register(freg_name)
- # Region Base corresponds to FLA bits 24:12
- range_base=self.cs.get_register_field(freg_name,freg,'RB')<<SPI_FLA_SHIFT
- # Region Limit corresponds to FLA bits 24:12
- range_limit=self.cs.get_register_field(freg_name,freg,'RL')<<SPI_FLA_SHIFT
- # FLA bits 11:0 are assumed to be FFFh for the limit comparison
- range_limit|=SPI_FLA_PAGE_MASK
- return(range_base,range_limit,freg)
-
- SpiRegions=Dict[int,Tuple[int,int,int,str,int]]
-
- # all_regions = True : return all SPI regions
- # all_regions = False: return only available SPI regions (limit >= base)
-
[docs]defcheck_hardware_sequencing(self)->None:
- # Test if the flash decriptor is valid (and hardware sequencing enabled)
- fdv=self.cs.read_register_field('HSFS','FDV')
- iffdv==0:
- self.logger.log_error("HSFS.FDV is 0, hardware sequencing is disabled")
- raiseSpiRuntimeError("Chipset does not support hardware sequencing")
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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
-#
-
-"""
-SPI Flash Descriptor binary parsing functionality
-
-
-usage:
- >>> fd = read_file( fd_file )
- >>> parse_spi_flash_descriptor( fd )
-"""
-
-importstruct
-fromtypingimportDict,List,Optional,Tuple
-fromchipsec.loggerimportlogger,print_buffer_bytes
-fromchipsec.halimportspi
-
-SPI_FLASH_DESCRIPTOR_SIGNATURE=struct.pack('=I',0x0FF0A55A)
-SPI_FLASH_DESCRIPTOR_SIZE=0x1000
-
-
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2018-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
-#
-
-"""
-JEDED ID : Manufacturers and Device IDs
-"""
-
-fromtypingimportDict
-
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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: Platform Hardware Security Assessment Framework
-#
-# -------------------------------------------------------------------------------
-
-"""
-UEFI firmware image parsing and manipulation functionality
-
-usage:
- >>> parse_uefi_region_from_file(_uefi, filename, fwtype, outpath):
-"""
-
-importos
-importstruct
-importrandom
-importjson
-importstring
-fromuuidimportUUID
-fromtypingimportDict,List,Optional,Union,Any,Callable,TYPE_CHECKING
-ifTYPE_CHECKING:
- fromchipsec.hal.uefi_fvimportEFI_MODULE
-fromchipsec.loggerimportlogger
-fromchipsec.fileimportwrite_file,read_file
-fromchipsec.hal.uefi_compressionimportCOMPRESSION_TYPE_LZMA,COMPRESSION_TYPE_EFI_STANDARD,COMPRESSION_TYPES_ALGORITHMS,COMPRESSION_TYPE_UNKNOWN,COMPRESSION_TYPE_LZMAF86
-fromchipsec.hal.uefi_commonimportbit_set,EFI_GUID_SIZE,EFI_GUID_FMT
-fromchipsec.hal.uefi_platformimportFWType,fw_types,EFI_NVRAM_GUIDS,EFI_PLATFORM_FS_GUIDS,NVAR_NVRAM_FS_FILE
-fromchipsec.hal.uefiimportidentify_EFI_NVRAM,parse_EFI_variables
-fromchipsec.hal.uefi_fvimportEFI_SECTION_PE32,EFI_SECTION_TE,EFI_SECTION_PIC,EFI_SECTION_COMPATIBILITY16,EFI_FIRMWARE_FILE_SYSTEM2_GUID
-fromchipsec.hal.uefi_fvimportEFI_FIRMWARE_FILE_SYSTEM_GUID,EFI_SECTIONS_EXE,EFI_SECTION_USER_INTERFACE,EFI_SECTION_GUID_DEFINED
-fromchipsec.hal.uefi_fvimportEFI_GUID_DEFINED_SECTION,EFI_GUID_DEFINED_SECTION_size,NextFwFile,NextFwFileSection,NextFwVolume,GetFvHeader
-fromchipsec.hal.uefi_fvimportEFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID,LZMA_CUSTOM_DECOMPRESS_GUID,TIANO_DECOMPRESSED_GUID,LZMAF86_DECOMPRESS_GUID
-fromchipsec.hal.uefi_fvimportEFI_CERT_TYPE_RSA_2048_SHA256_GUID,EFI_CERT_TYPE_RSA_2048_SHA256_GUID_size,EFI_SECTION,EFI_FV,EFI_FILE
-fromchipsec.hal.uefi_fvimportEFI_FIRMWARE_CONTENTS_SIGNED_GUID,WIN_CERT_TYPE_EFI_GUID,WIN_CERTIFICATE_size,WIN_CERTIFICATE
-fromchipsec.hal.uefi_fvimportEFI_SECTION_COMPRESSION,EFI_SECTION_FIRMWARE_VOLUME_IMAGE,EFI_SECTION_RAW,SECTION_NAMES,DEF_INDENT
-fromchipsec.hal.uefi_fvimportFILE_TYPE_NAMES,EFI_FS_GUIDS,EFI_FILE_HEADER_INVALID,EFI_FILE_HEADER_VALID,EFI_FILE_HEADER_CONSTRUCTION
-fromchipsec.hal.uefi_fvimportEFI_COMPRESSION_SECTION_size,EFI_FV_FILETYPE_ALL,EFI_FV_FILETYPE_FFS_PAD,EFI_FVB2_ERASE_POLARITY,EFI_FV_FILETYPE_RAW
-fromchipsec.hal.uefi_compressionimportUEFICompression
-
-CMD_UEFI_FILE_REMOVE=0
-CMD_UEFI_FILE_INSERT_BEFORE=1
-CMD_UEFI_FILE_INSERT_AFTER=2
-CMD_UEFI_FILE_REPLACE=3
-
-type2ext={EFI_SECTION_PE32:'pe32',EFI_SECTION_TE:'te',EFI_SECTION_PIC:'pic',EFI_SECTION_COMPATIBILITY16:'c16'}
-
-#
-# Calculate hashes for all FVs, FW files and sections (PE/COFF or TE executables)
-# and write them on the file system
-#
-WRITE_ALL_HASHES=False
-
-
-
-
-
-#
-# build_efi_file_tree - extract EFI FV file from EFI image and build an object tree
-#
-# Input arguements:
-# fv_image - fv_image containing files
-# fwtype - platform specific firmware type used to detect NVRAM format (VSS, EVSA, NVAR...)
-
-
-
-#
-# build_efi_tree - extract EFI modules (FV, files, sections) from EFI image and build an object tree
-#
-# Input arguments:
-# data - an image containing UEFI firmware volumes
-# fwtype - platform specific firmware type used to detect NVRAM format (VSS, EVSA, NVAR...)
-#
-
-
-
-#
-# Attempt to find efi modules using calls to build_efi_tree, build_efi_file_tree,
-# and build_efi_modules_tree in succession. Return once one of the calls is successful
-#
-
-
-
-#
-# update_efi_tree propagates EFI file's GUID down to all sections and
-# UI_string from the corresponding section, if found, up to the EFI file at the same time
-# File GUID and UI string are then used when searching for EFI files and executable sections
-#
-
[docs]defupdate_efi_tree(modules:List['EFI_MODULE'],parent_guid:Optional[UUID]=None)->str:
- ui_string=''
- forminmodules:
- iftype(m)==EFI_FILE:
- parent_guid=m.Guid
- eliftype(m)==EFI_SECTION:
- # if it's a section update its parent file's GUID
- m.parentGuid=parent_guid
- ifm.Type==EFI_SECTION_USER_INTERFACE:
- # if UI section (leaf), update ui_string in sibling sections including in PE/TE,
- # and propagate it up until and including parent EFI file
- form1inmodules:
- m1.ui_string=m.ui_string
- ui_string=m.ui_string
- # update parent file's GUID in all children nodes
- iflen(m.children)>0:
- ui_string=update_efi_tree(m.children,parent_guid)
- # if it's a EFI file then update its ui_string with ui_string extracted from UI section
- ifui_stringand(type(m)in(EFI_FILE,EFI_SECTION)):
- m.ui_string=ui_string
- if(type(m)==EFI_FILE):
- ui_string=''
- returnui_string
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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
-#
-
-
-"""
-Trusted Platform Module (TPM) HAL component
-
-https://trustedcomputinggroup.org
-"""
-
-importstruct
-fromcollectionsimportnamedtuple
-fromtypingimportDict,Tuple,Callable
-
-fromchipsec.loggerimportprint_buffer_bytes
-fromchipsec.halimporthal_base
-importchipsec.hal.tpm12_commands
-
-
-COMMANDREADY=0x40
-TPMGO=0x20
-HEADERSIZE=0x0A
-HEADERFORMAT='>HII'
-BEENSEIZED=0x10
-REQUESTUSE=0x2
-ACTIVELOCALITY=0x20
-DATAAVAIL=0x10
-
-TPM_DATAFIFO=0x0024
-TPM_STS=0x0018
-TPM_DIDVID=0x0F00
-TPM_ACCESS=0x0000
-TPM_RID=0x0F04
-TPM_INTCAP=0x0014
-TPM_INTENABLE=0x0008
-
-STATUS:Dict[int,str]={
- 0x00:"Success",
- 0x01:"ERROR: Authentication Failed",
- 0x02:"ERROR: The index to a PCR, DIR or other register is incorrect",
- 0x03:"ERROR: One or more parameter is bad",
- 0x04:"ERROR: An operation completed successfully but the auditing of that operation failed",
- 0x05:"ERROR: The clear disable flag is set and all clear operations now require physical access",
- 0x06:"ERROR: The TPM is deactivated",
- 0x07:"ERROR: The TPM is disabled",
- 0x08:"ERROR: The target command has been disabled",
- 0x09:"ERROR: The operation failed",
- 0x0A:"ERROR: The ordinal was unknown or inconsistent",
- 0x0B:"ERROR: The ability to install an owner is disabled",
- 0x0C:"ERROR: The key handle can not be interpreted",
- 0x0D:"ERROR: The key handle points to an invalid key",
- 0x0E:"ERROR: Unacceptable encryption scheme",
- 0x0F:"ERROR: Migration authorization failed",
- 0x10:"ERROR: PCR information could not be interpreted",
- 0x11:"ERROR: No room to load key",
- 0x12:"ERROR: There is no SRK set",
- 0x13:"ERROR: An encrypted blob is invalid or was not created by this TPM",
- 0x14:"ERROR: There is already an Owner",
- 0x15:"ERROR: The TPM has insufficient internal resources to perform the requested action",
- 0x16:"ERROR: A random string was too short",
- 0x17:"ERROR: The TPM does not have the space to perform the operation",
- 0x18:"ERROR: The named PCR value does not match the current PCR value.",
- 0x19:"ERROR: The paramSize argument to the command has the incorrect value",
- 0x1A:"ERROR: There is no existing SHA-1 thread.",
- 0x1B:"ERROR: The calculation is unable to proceed because the existing SHA-1 thread has already encountered an error",
- 0x1C:"ERROR: Self-test has failed and the TPM has shut-down",
- 0x1D:"ERROR: The authorization for the second key in a 2 key function failed authorization",
- 0x1E:"ERROR: The tag value sent to for a command is invalid",
- 0x1F:"ERROR: An IO error occurred transmitting information to the TPM",
- 0x20:"ERROR: The encryption process had a problem",
- 0x21:"ERROR: The decryption process did not complete",
- 0x22:"ERROR: An invalid handle was used",
- 0x23:"ERROR: The TPM does not a EK installed",
- 0x24:"ERROR: The usage of a key is not allowed",
- 0x25:"ERROR: The submitted entity type is not allowed",
- 0x26:"ERROR: The command was received in the wrong sequence relative to TPM_Init and a subsequent TPM_Startup",
- 0x27:"ERROR: Signed data cannot include additional DER information",
- 0x28:"ERROR: The key properties in TPM_KEY_PARMs are not supported by this TPM",
- 0x29:"ERROR: The migration properties of this key are incorrect",
- 0x2A:"ERROR: The signature or encryption scheme for this key is incorrect or not permitted in this situation",
- 0x2B:"ERROR: The size of the data (or blob) parameter is bad or inconsistent with the referenced key",
- 0x2C:"ERROR: A parameter is bad",
- 0x2D:"ERROR: Either the physicalPresence or physicalPresenceLock bits have the wrong value",
- 0x2E:"ERROR: The TPM cannot perform this version of the capability",
- 0x2F:"ERROR: The TPM does not allow for wrapped transport sessions",
- 0x30:"ERROR: TPM audit construction failed and the underlying command was returning a failure code also",
- 0x31:"ERROR: TPM audit construction failed and the underlying command was returning success",
- 0x32:"ERROR: Attempt to reset a PCR register that does not have the resettable attribute",
- 0x33:"ERROR: Attempt to reset a PCR register that requires locality and locality modifier not part of command transport",
- 0x34:"ERROR: Make identity blob not properly typed",
- 0x35:"ERROR: When saving context identified resource type does not match actual resource",
- 0x36:"ERROR: The TPM is attempting to execute a command only available when in FIPS mode",
- 0x37:"ERROR: The command is attempting to use an invalid family ID",
- 0x38:"ERROR: The permission to manipulate the NV storage is not available",
- 0x39:"ERROR: The operation requires a signed command",
- 0x3A:"ERROR: Wrong operation to load an NV key",
- 0x3B:"ERROR: NV_LoadKey blob requires both owner and blob authorization",
- 0x3C:"ERROR: The NV area is locked and not writeable",
- 0x3D:"ERROR: The locality is incorrect for the attempted operation",
- 0x3E:"ERROR: The NV area is read only and can?t be written to",
- 0x3F:"ERROR: There is no protection on the write to the NV area",
- 0x40:"ERROR: The family count value does not match",
- 0x41:"ERROR: The NV area has already been written to",
- 0x42:"ERROR: The NV area attributes conflict",
- 0x43:"ERROR: The structure tag and version are invalid or inconsistent",
- 0x44:"ERROR: The key is under control of the TPM Owner and can only be evicted by the TPM Owner",
- 0x45:"ERROR: The counter handle is incorrect",
- 0x46:"ERROR: The write is not a complete write of the area",
- 0x47:"ERROR: The gap between saved context counts is too large",
- 0x48:"ERROR: The maximum number of NV writes without an owner has been exceeded",
- 0x49:"ERROR: No operator AuthData value is set",
- 0x4A:"ERROR: The resource pointed to by context is not loaded",
- 0x4B:"ERROR: The delegate administration is locked",
- 0x4C:"ERROR: Attempt to manage a family other then the delegated family",
- 0x4D:"ERROR: Delegation table management not enabled",
- 0x4E:"ERROR: There was a command executed outside of an exclusive transport session",
- 0x4F:"ERROR: Attempt to context save a owner evict controlled key",
- 0x50:"ERROR: The DAA command has no resources available to execute the command",
- 0x51:"ERROR: The consistency check on DAA parameter inputData0 has failed",
- 0x52:"ERROR: The consistency check on DAA parameter inputData1 has failed",
- 0x53:"ERROR: The consistency check on DAA_issuerSettings has failed",
- 0x54:"ERROR: The consistency check on DAA_tpmSpecific has failed",
- 0x55:"ERROR: The atomic process indicated by the submitted DAA command is not the expected process",
- 0x56:"ERROR: The issuer's validity check has detected an inconsistency",
- 0x57:"ERROR: The consistency check on w has failed",
- 0x58:"ERROR: The handle is incorrect",
- 0x59:"ERROR: Delegation is not correct",
- 0x5A:"ERROR: The context blob is invalid",
- 0x5B:"ERROR: Too many contexts held by the TPM",
- 0x5C:"ERROR: Migration authority signature validation failure",
- 0x5D:"ERROR: Migration destination not authenticated",
- 0x5E:"ERROR: Migration source incorrect",
- 0x5F:"ERROR: Incorrect migration authority",
- 0x60:"ERROR: TBD",
- 0x61:"ERROR: Attempt to revoke the EK and the EK is not revocable",
- 0x62:"ERROR: Bad signature of CMK ticket",
- 0x63:"ERROR: There is no room in the context list for additional contexts",
- 0x800:"NON-FATAL ERROR: The TPM is too busy to respond to the command immediately, but the command could be resubmitted at a later time",
- 0x801:"NON-FATAL ERROR: TPM_ContinueSelfTest has not been run.",
- 0x802:"NON-FATAL ERROR: The TPM is currently executing the actions of TPM_ContinueSelfTest because the ordinal required resources that have not been tested",
- 0x803:"NON-FATAL ERROR: The TPM is defending against dictionary attacks and is in some time-out period."
-}
-
-LOCALITY:Dict[str,int]={
- '0':0x0000,
- '1':0x1000,
- '2':0x2000,
- '3':0x3000,
- '4':0x4000
-}
-
-COMMANDS:Dict[str,Callable]={
- "pcrread":chipsec.hal.tpm12_commands.pcrread,
- "nvread":chipsec.hal.tpm12_commands.nvread,
- "startup":chipsec.hal.tpm12_commands.startup,
- "continueselftest":chipsec.hal.tpm12_commands.continueselftest,
- "forceclear":chipsec.hal.tpm12_commands.forceclear
-}
-
-
-
[docs]defdump_access(self,locality:str)->None:
- """View the contents of the register used to gain ownership of the TPM"""
- register='TPM_ACCESS'
- self.dump_register(register,locality)
-
-
[docs]defdump_status(self,locality:str)->None:
- """View general status details"""
- register='TPM_STS'
- self.dump_register(register,locality)
[docs]defdump_intcap(self,locality:str)->None:
- """Provides information of which interrupts that particular TPM supports"""
- register='TPM_INTF_CAPABILITY'
- self.dump_register(register,locality)
-
-
[docs]defdump_intenable(self,locality:str)->None:
- """View the contents of the register used to enable specific interrupts"""
- register='TPM_INT_ENABLE'
- self.dump_register(register,locality)
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-2020, 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
-#
-
-
-"""
-Definition for TPMv1.2 commands to use with TPM HAL
-
-TCG PC Client TPM Specification
-TCG TPM v1.2 Specification
-"""
-
-importstruct
-fromtypingimportDict,Tuple
-fromchipsec.loggerimportlogger
-
-COMMAND_FORMAT="=HIIIII"
-
-TPM_TAG_RQU_COMMAND=0xc100
-TPM_TAG_RQU_AUTH1_COMMAND=0xc200
-TPM_TAG_RQU_AUTH2_COMMAND=0xC300
-TPM_TAG_RSP_COMMAND=0xC400
-TPM_TAG_RSP_AUTH1_COMMAND=0xC500
-TPM_TAG_RSP_AUTH2_COMMAND=0xC600
-
-TPM_ORD_CONTINUESELFTEST=0x53000000
-TPM_ORD_FORCECLEAR=0x5D000000
-TPM_ORD_GETCAPABILITY=0x65000000
-TPM_ORD_NV_DEFINESPACE=0xCC000000
-TPM_ORD_NV_READVALUE=0xCF000000
-TPM_ORD_NV_WRITEVALUE=0xCD000000
-TPM_ORD_PCRREAD=0x15000000
-TPM_ORD_PHYSICALDISABLE=0x70000000
-TPM_ORD_PHYSICALENABLE=0x6F000000
-TPM_ORD_PHYSICALSETDEACTIVATED=0x72000000
-TPM_ORD_STARTUP=0x99000000
-TPM_ORD_SAVESTATE=0x98000000
-TSC_ORD_PHYSICALPRESENCE=0x0A000040
-TSC_ORD_RESETESTABLISHMENTBIT=0x0B000040
-
-STARTUP:Dict[int,int]={
- 1:0x0100,
- 2:0x0200,
- 3:0x0300
-}
-
-PCR:Dict[int,int]={
- 0:0x00000000,
- 1:0x01000000,
- 2:0x02000000,
- 3:0x03000000,
- 4:0x04000000,
- 5:0x05000000,
- 6:0x06000000,
- 7:0x07000000,
- 8:0x08000000,
- 9:0x09000000,
- 10:0x0a000000,
- 11:0x0b000000,
- 12:0x0c000000,
- 13:0x0d000000,
- 14:0x0e000000,
- 15:0x0f000000,
- 16:0x10000000,
- 17:0x11000000,
- 18:0x12000000,
- 19:0x13000000,
- 20:0x14000000,
- 21:0x15000000,
- 22:0x16000000,
- 23:0x17000000,
- 24:0x18000000,
- 25:0x19000000,
- 26:0x1a000000,
- 27:0x1b000000,
- 28:0x1c000000,
- 29:0x1d000000,
- 30:0x1e000000
-}
-
-
-
[docs]defpcrread(*command_argv:str)->Tuple[bytes,int]:
- """
- The TPM_PCRRead operation provides non-cryptographic reporting of the contents of a named PCR
- """
- Size=0x0E000000
- try:
- Pcr=PCR[int(command_argv[0])]
- except:
- iflogger().HAL:
- logger().log_bad("Invalid PCR value\n")
- return(b'',0)
- command=struct.pack(COMMAND_FORMAT,TPM_TAG_RQU_COMMAND,Size,TPM_ORD_PCRREAD,Pcr,0,0)
- size=Size>>0x18
- return(command,size)
-
-
-
[docs]defnvread(*command_argv:str)->Tuple[bytes,int]:
- """
- Read a value from the NV store
- Index, Offset, Size
- """
- Size=0x18000000
- command=struct.pack(COMMAND_FORMAT,TPM_TAG_RQU_COMMAND,Size,TPM_ORD_NV_READVALUE,int(command_argv[0],16),int(command_argv[1],16),int(command_argv[2],16))
- size=Size>>0x18
- return(command,size)
-
-
-
[docs]defstartup(*command_argv:str)->Tuple[bytes,int]:
- """
- Execute a tpm_startup command. TPM_Startup is always preceded by TPM_Init, which is the physical indication (a system wide reset) that TPM initialization is necessary
- Type of Startup to be used:
- 1: TPM_ST_CLEAR
- 2: TPM_ST_STATE
- 3: TPM_ST_DEACTIVATED
- """
- try:
- startupType=STARTUP[int(command_argv[0])]
- except:
- iflogger().HAL:
- logger().log_bad("Invalid startup type option value\n")
- return(b'',0)
- Size=0x0E000000
- command=struct.pack(COMMAND_FORMAT,TPM_TAG_RQU_COMMAND,Size,TPM_ORD_STARTUP,startupType,0,0)
- size=Size>>0x18
- return(command,size)
-
-
-
[docs]defcontinueselftest(*command_argv:str)->Tuple[bytes,int]:
- """
- TPM_ContinueSelfTest informs the TPM that it should complete self-test of all TPM functions. The TPM may return success immediately and then perform the self-test, or it may perform the self-test and then return success or failure.
- """
- Size=0x0A000000
- command=struct.pack(COMMAND_FORMAT,TPM_TAG_RQU_COMMAND,Size,TPM_ORD_CONTINUESELFTEST,0,0,0)
- size=Size>>0x18
- return(command,size)
-
-
-
[docs]defgetcap(*command_argv:str)->Tuple[bytes,int]:
- """
- Returns current information regarding the TPM
- CapArea - Capabilities Area
- SubCapSize - Size of SubCapabilities
- SubCap - Subcapabilities
- """
- Size=0x18000000
- command=struct.pack(COMMAND_FORMAT,TPM_TAG_RQU_COMMAND,Size,TPM_ORD_GETCAPABILITY,int(command_argv[0],16),int(command_argv[1],16),int(command_argv[2],16))
- size=Size>>0x18
- return(command,size)
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2017, Google Inc
-# Copyright (c) 2019-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.
-#
-
-"""
-Trusted Platform Module Event Log
-
-Based on the following specifications:
-
-`TCG EFI Platform Specification For TPM Family 1.1 or 1.2 <https://trustedcomputinggroup.org/wp-content/uploads/TCG_EFI_Platform_1_22_Final_-v15.pdf>`_
-
-`TCG PC Client Specific Implementation Specification for Conventional BIOS", version 1.21 <https://trustedcomputinggroup.org/wp-content/uploads/TCG_PCClientImplementation_1-21_1_00.pdf>`_
-
-`TCG EFI Protocol Specification, Family "2.0" <https://trustedcomputinggroup.org/wp-content/uploads/EFI-Protocol-Specification-rev13-160330final.pdf>`_
-
-`TCG PC Client Platform Firmware Profile Specification <https://trustedcomputinggroup.org/wp-content/uploads/PC-ClientSpecific_Platform_Profile_for_TPM_2p0_Systems_v51.pdf>`_
-"""
-
-importstruct
-
-fromtypingimportAny,Dict,BinaryIO,Optional,Type,TypeVar
-fromchipsec.loggerimportlogger
-
-EventType=TypeVar('EventType',bound='TcgPcrEvent')
-
-
[docs]classTcgPcrEvent:
- """An Event (TPM 1.2 format) as recorded in the SML."""
-
- _header_fmt="II20sI"
- _header_size=struct.calcsize(_header_fmt)
-
- def__init__(self,pcr_index:int,event_type:int,digest:bytes,event_size:int,event:Any):
- self.pcr_index=pcr_index
- self.event_type=event_type
- name=SML_EVENT_TYPE.get(self.event_type)
- ifisinstance(name,str):
- self.event_type_name=name
- self.digest=digest
- self.event_size=event_size
- self.event=event
-
-
[docs]@classmethod
- defparse(cls:Type[EventType],log:BinaryIO)->Optional[EventType]:
- """Try to read an event from the log.
-
- Args:
- log (file-like): Log where the event is stored.
-
- Returns:
- An instance of the created event. If a subclass
- exists for such event_type, an object of this class
- is returned. Otherwise, a TcgPcrEvent is returned.
- """
- header=log.read(cls._header_size)
- ifnotheader:
- returnNone
- fields=struct.unpack(cls._header_fmt,header)
- pcr_index,event_type,digest,event_size=fields
- event=log.read(event_size)
- iflen(event)!=event_size:
- logger().log_warning("[tpm_eventlog] event data length does not match the expected size")
- name=SML_EVENT_TYPE.get(event_type)
- kls=clsifisinstance(name,str)elsename
- ifklsisNone:
- returnNone
- returnkls(pcr_index,event_type,digest,event_size,event)
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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
-#
-
-"""
-Microcode update specific functionality (for each CPU thread)
-
-usage:
- >>> ucode_update_id( 0 )
- >>> load_ucode_update( 0, ucode_buf )
- >>> update_ucode_all_cpus( 'ucode.pdb' )
- >>> dump_ucode_update_header( 'ucode.pdb' )
-"""
-
-importstruct
-importos
-fromtypingimportAnyStr
-fromchipsec.loggerimportlogger
-fromchipsec.fileimportread_file
-
-IA32_MSR_BIOS_UPDT_TRIG=0x79
-IA32_MSR_BIOS_SIGN_ID=0x8B
-IA32_MSR_BIOS_SIGN_ID_STATUS=0x1
-
-
-fromcollectionsimportnamedtuple
-
-
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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
-#
-
-"""
-Main UEFI component using platform specific and common UEFI functionality
-"""
-
-importstruct
-importos
-fromtypingimportDict,List,Optional,Tuple,TYPE_CHECKING
-ifTYPE_CHECKING:
- fromchipsec.hal.uefi_commonimportS3BOOTSCRIPT_ENTRY,EFI_SYSTEM_TABLE
- fromchipsec.hal.uefi_platformimportEfiVariableType,EfiTableType
-fromchipsec.halimporthal_base,uefi_platform
-fromchipsec.hal.uefi_commonimportEFI_VENDOR_TABLE,EFI_VENDOR_TABLE_SIZE,EFI_VENDOR_TABLE_FORMAT,EFI_TABLE_HEADER_SIZE,EFI_TABLE_HEADER,EFI_TABLES,MAX_EFI_TABLE_SIZE
-fromchipsec.hal.uefi_commonimportS3BootScriptOpcode,S3_BOOTSCRIPT_VARIABLES,parse_efivar_file,EFI_REVISIONS,AUTH_SIG_VAR,ESAL_SIG_VAR
-fromchipsec.hal.uefi_commonimportEFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS,EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS,EFI_VARIABLE_APPEND_WRITE,EFI_VARIABLE_NON_VOLATILE
-fromchipsec.hal.uefi_commonimportEFI_VARIABLE_BOOTSERVICE_ACCESS,EFI_VARIABLE_RUNTIME_ACCESS,EFI_VARIABLE_HARDWARE_ERROR_RECORD,SECURE_BOOT_SIG_VAR
-fromchipsec.hal.uefi_commonimportIS_VARIABLE_ATTRIBUTE,EFI_TABLE_HEADER_FMT,EFI_SYSTEM_TABLE_SIGNATURE,EFI_RUNTIME_SERVICES_SIGNATURE,EFI_BOOT_SERVICES_SIGNATURE
-fromchipsec.hal.uefi_commonimportEFI_DXE_SERVICES_TABLE_SIGNATURE,EFI_CONFIGURATION_TABLE,ACPI_VARIABLE_SET_STRUCT_SIZE
-fromchipsec.loggerimportlogger,print_buffer_bytes
-fromchipsec.fileimportwrite_file,read_file
-fromchipsec.definesimportbytestostring
-fromchipsec.helper.oshelperimportOsHelperError
-
-
-
-########################################################################################################
-#
-# S3 Resume Boot-Script Parsing Functionality
-#
-########################################################################################################
-
-
[docs]defparse_script(script:bytes,log_script:bool=False)->List['S3BOOTSCRIPT_ENTRY']:
- off=0
- entry_type=0
- s3_boot_script_entries=[]
- len_s=len(script)
-
- iflog_script:
- logger().log('[uefi] +++ S3 Resume Boot-Script +++\n')
- script_type,script_header_length=uefi_platform.id_s3bootscript_type(script,log_script)
- off+=script_header_length
-
- while(off<len_s)and(entry_type!=S3BootScriptOpcode.EFI_BOOT_SCRIPT_TERMINATE_OPCODE):
- entry_type,s3script_entry=uefi_platform.parse_s3bootscript_entry(script_type,script,off,log_script)
- # couldn't parse the next entry - return what has been parsed so far
- ifs3script_entryisNone:
- returns3_boot_script_entries
- s3_boot_script_entries.append(s3script_entry)
- off+=s3script_entry.length
-
- iflog_script:
- logger().log('[uefi] +++ End of S3 Resume Boot-Script +++')
-
- logger().log_hal(f'[uefi] S3 Resume Boot-Script size: 0x{off:X}')
- logger().log_hal('\n[uefi] [++++++++++ S3 Resume Boot-Script Buffer ++++++++++]')
- iflogger().HAL:
- print_buffer_bytes(script[:off])
-
- returns3_boot_script_entries
[docs]deffind_EFI_Configuration_Table(self)->Tuple[bool,int,Optional[EFI_CONFIGURATION_TABLE],bytes]:
- ect_pa=0
- ect=None
- ect_buf=b''
- (isFound,_,_,est,_)=self.find_EFI_System_Table()
- ifisFoundandestisnotNone:
- if0!=est.BootServices:
- logger().log_hal('[uefi] UEFI appears to be in Boot mode')
- ect_pa=est.ConfigurationTable
- else:
- logger().log_hal('[uefi] UEFI appears to be in Runtime mode')
- ect_pa=self.cs.mem.va2pa(est.ConfigurationTable)
- ifnotect_pa:
- # Most likely the VA in the System Table is not mapped so find the RST by signature and
- # then compute the address of the configuration table. This assumes the VA mapping keeps
- # the pages in the same relative location as in physical memory.
- (rst_found,rst_pa,rst_header,rst,rst_buf)=self.find_EFI_RuntimeServices_Table()
- ifrst_found:
- iflogger().HAL:
- logger().log_warning('Attempting to derive configuration table address')
- ect_pa=rst_pa+(est.ConfigurationTable-est.RuntimeServices)
- else:
- iflogger().HAL:
- logger().log_warning("Can't find UEFI ConfigurationTable")
- return(False,ect_pa,ect,ect_buf)
- ifestisnotNone:
- logger().log_hal(f'[uefi] EFI Configuration Table ({est.NumberOfTableEntries:d} entries): VA = 0x{est.ConfigurationTable:016X}, PA = 0x{ect_pa:016X}')
- else:
- logger().log_hal(f'[uefi] EFI Configuration Table (No entries found)')
-
- found=ect_paisnotNone
- iffoundand(estisnotNone):
- ect_buf=self.cs.mem.read_physical_mem(ect_pa,EFI_VENDOR_TABLE_SIZE*est.NumberOfTableEntries)
- ect=EFI_CONFIGURATION_TABLE()
- foriinrange(est.NumberOfTableEntries):
- vt=EFI_VENDOR_TABLE(*struct.unpack_from(EFI_VENDOR_TABLE_FORMAT,ect_buf[i*EFI_VENDOR_TABLE_SIZE:]))
- ect.VendorTables[vt.VendorGuid()]=vt.VendorTable
- return(found,ect_pa,ect,ect_buf)
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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
-#
-
-
-"""
-Common UEFI/EFI functionality including UEFI variables, Firmware Volumes, Secure Boot variables, S3 boot-script, UEFI tables, etc.
-"""
-
-importos
-importstruct
-importcodecs
-fromcollectionsimportnamedtuple
-fromuuidimportUUID
-fromtypingimportDict,List,Tuple,Optional,Any,Callable
-
-fromchipsec.fileimportread_file,write_file
-fromchipsec.loggerimportlogger,dump_buffer,dump_buffer_bytes
-fromchipsec.definesimportbytestostring
-
-# from chipsec.helper.oshelper import helper
-
-
-################################################################################################
-#
-# EFI Variable and Variable Store Defines
-#
-################################################################################################
-
-# UDK2010.SR1\MdeModulePkg\Include\Guid\VariableFormat.h
-#
-# Variable data start flag.
-#
-VARIABLE_DATA=0x55aa
-VARIABLE_DATA_SIGNATURE=struct.pack('=H',VARIABLE_DATA)
-
-
-#
-# Variable Attributes
-#
-EFI_VARIABLE_NON_VOLATILE=0x00000001# Variable is non volatile
-EFI_VARIABLE_BOOTSERVICE_ACCESS=0x00000002# Variable is boot time accessible
-EFI_VARIABLE_RUNTIME_ACCESS=0x00000004# Variable is run-time accessible
-EFI_VARIABLE_HARDWARE_ERROR_RECORD=0x00000008
-EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS=0x00000010# Variable is authenticated
-EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS=0x00000020# Variable is time based authenticated
-EFI_VARIABLE_APPEND_WRITE=0x00000040# Variable allows append
-EFI_VARIABLE_ENHANCED_AUTHENTICATED_ACCESS=0x00000080
-UEFI23_1_AUTHENTICATED_VARIABLE_ATTRIBUTES=(EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS|EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS|EFI_VARIABLE_ENHANCED_AUTHENTICATED_ACCESS)
-
-
-
[docs]defparse_sb_db(db:bytes,decode_dir:str)->List[bytes]:
- entries=[]
- dof=0
- nsig=0
- db_size=len(db)
- if0==db_size:
- returnentries
-
- # some platforms have 0's in the beginnig, skip all 0 (no known SignatureType starts with 0x00):
- while(dof+SIGNATURE_LIST_size)<db_size:
- SignatureType0,SignatureListSize,SignatureHeaderSize,SignatureSize \
- =struct.unpack(SIGNATURE_LIST,db[dof:dof+SIGNATURE_LIST_size])
-
- # prevent infinite loop when parsing malformed var
- ifSignatureListSize==0:
- logger().log_bad("db parsing failed!")
- returnentries
-
- # Determine the signature type
- SignatureType=EFI_GUID_STR(SignatureType0)
- sig_parse_f=None
- sig_size=0
- if(SignatureTypeinsig_types.keys()):
- sig_name,sig_parse_f,sig_size,short_name=sig_types[SignatureType]
- else:
- logger().log_bad(f'Unknown signature type {SignatureType}, skipping signature decode.')
- dof+=SignatureListSize
- continue
-
- # Extract signature data blobs
- if(((sig_size>0)and(sig_size==SignatureSize))or((sig_size==0)and(SignatureSize>=0x10))):
- sof=0
- sig_list=db[dof+SIGNATURE_LIST_size+SignatureHeaderSize:dof+SignatureListSize]
- sig_list_size=len(sig_list)
- while((sof+EFI_GUID_SIZE)<sig_list_size):
- sig_data=sig_list[sof:sof+SignatureSize]
- owner0=struct.unpack(EFI_GUID_FMT,sig_data[:EFI_GUID_SIZE])[0]
- owner=EFI_GUID_STR(owner0)
- data=sig_data[EFI_GUID_SIZE:]
- entries.append(data)
- sig_file_name=f'{short_name}-{owner}-{nsig:02d}.bin'
- sig_file_name=os.path.join(decode_dir,sig_file_name)
- write_file(sig_file_name,data)
- if(sig_parse_fisnotNone):
- sig_parse_f(data)
- sof=sof+SignatureSize
- nsig=nsig+1
- else:
- err_str=f'Wrong SignatureSize for {SignatureType} type: 0x{SignatureSize:X}.'
- if(sig_size>0):
- err_str=err_str+f' Must be 0x{sig_size:X}.'
- else:
- err_str=err_str+" Must be >= 0x10."
- logger().log_error(err_str)
- logger().log_error('Skipping signature decode for this list.')
- dof=dof+SignatureListSize
-
- returnentries
-
-
-#
-# "certdb" variable stores the signer's certificates for non PK/KEK/DB/DBX
-# variables with EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS|EFI_VARIABLE_NON_VOLATILE set.
-# "certdbv" variable stores the signer's certificates for non PK/KEK/DB/DBX
-# variables with EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS set
-#
-# GUID: gEfiCertDbGuid
-#
-# We need maintain atomicity.
-#
-# Format:
-# +----------------------------+
-# | UINT32 | <-- CertDbListSize, including this UINT32
-# +----------------------------+
-# | AUTH_CERT_DB_DATA | <-- First CERT
-# +----------------------------+
-# | ........ |
-# +----------------------------+
-# | AUTH_CERT_DB_DATA | <-- Last CERT
-# +----------------------------+
-#
-# typedef struct {
-# EFI_GUID VendorGuid;
-# UINT32 CertNodeSize;
-# UINT32 NameSize;
-# UINT32 CertDataSize;
-# /// CHAR16 VariableName[NameSize];
-# /// UINT8 CertData[CertDataSize];
-# } AUTH_CERT_DB_DATA;
-#
-AUTH_CERT_DB_LIST_HEAD="<I"
-AUTH_CERT_DB_LIST_HEAD_size=struct.calcsize(AUTH_CERT_DB_LIST_HEAD)
-AUTH_CERT_DB_DATA="<16sIII"
-AUTH_CERT_DB_DATA_size=struct.calcsize(AUTH_CERT_DB_DATA)
-
-
-
[docs]defparse_auth_var(db:bytes,decode_dir:str)->List[bytes]:
- entries=[]
- dof=0
- nsig=0
- db_size=len(db)
-
- # Verify that list makes sense
- ifdb_size<AUTH_CERT_DB_LIST_HEAD_size:
- logger().log_warning("Cert list empty.")
- returnentries
- expected_size=struct.unpack(AUTH_CERT_DB_LIST_HEAD,db[dof:dof+AUTH_CERT_DB_LIST_HEAD_size])[0]
- ifdb_size!=expected_size:
- logger().log_error("Expected size of cert list did not match actual size.")
- returnentries
- dof+=AUTH_CERT_DB_LIST_HEAD_size
-
- # Loop through all the certs in the list.
- whiledof+AUTH_CERT_DB_DATA_size<db_size:
- ven_guid0,cert_node_size,name_size,cert_data_size=struct.unpack(AUTH_CERT_DB_DATA,db[dof:dof+AUTH_CERT_DB_DATA_size])
- vendor_guid=EFI_GUID_STR(ven_guid0)
- name_size*=2# Name size is actually the number of CHAR16 in the name array
- tof=dof+AUTH_CERT_DB_DATA_size
- try:
- var_name=codecs.decode(db[tof:tof+name_size],'utf-16')
- exceptUnicodeDecodeError:
- logger().log_warning(f'Unable to decode {db[tof:tof+name_size]}')
- var_name="chipsec.exceptions!"
- tof+=name_size
- sig_data=db[tof:tof+cert_data_size]
- entries.append(sig_data)
- sig_file_name=f'{vendor_guid}-{codecs.encode(var_name)}-{nsig:02X}.bin'
- sig_file_name=os.path.join(decode_dir,sig_file_name)
- write_file(sig_file_name,sig_data)
- dof+=cert_node_size
- nsig+=1
-
- returnentries
-# 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
-
-
-try:
- importbrotli
- has_brotli=True
-exceptImportError:
- has_brotli=False
-try:
- importlzma
- has_lzma=True
-exceptImportError:
- has_lzma=False
-try:
- importEfiCompressor
- has_eficomp=True
-exceptImportError:
- has_eficomp=False
-
-fromtypingimportList,Any
-fromchipsec.loggerimportlogger
-
-#
-# Compression Types
-#
-COMPRESSION_TYPE_NONE=0
-COMPRESSION_TYPE_TIANO=1
-COMPRESSION_TYPE_UEFI=2
-COMPRESSION_TYPE_LZMA=3
-COMPRESSION_TYPE_BROTLI=4
-COMPRESSION_TYPE_EFI_STANDARD=5
-COMPRESSION_TYPE_UNKNOWN=6
-COMPRESSION_TYPE_LZMAF86=7
-COMPRESSION_TYPES_ALGORITHMS:List[int]=[COMPRESSION_TYPE_LZMA,
- COMPRESSION_TYPE_TIANO,
- COMPRESSION_TYPE_UEFI,
- COMPRESSION_TYPE_BROTLI,
- COMPRESSION_TYPE_LZMAF86,
- COMPRESSION_TYPE_NONE,]
-COMPRESSION_TYPES:List[int]=[COMPRESSION_TYPE_NONE,
- COMPRESSION_TYPE_TIANO,
- COMPRESSION_TYPE_UEFI,
- COMPRESSION_TYPE_LZMA,
- COMPRESSION_TYPE_BROTLI,
- COMPRESSION_TYPE_EFI_STANDARD,
- COMPRESSION_TYPE_UNKNOWN,
- COMPRESSION_TYPE_LZMAF86,]
-
-
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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
-#
-
-"""
-Platform specific UEFI functionality (parsing platform specific EFI NVRAM, capsules, etc.)
-"""
-
-importstruct
-fromcollectionsimportnamedtuple
-fromuuidimportUUID
-fromtypingimportDict,List,Tuple,Optional,Union,Any
-fromchipsecimportdefines
-fromchipsec.loggerimportlogger
-fromchipsec.hal.uefi_commonimportbit_set,VARIABLE_SIGNATURE_VSS,S3BootScriptOpcode_MDE,op_io_pci_mem,S3BootScriptOpcode_EdkCompat,EFI_GUID_STR,EFI_GUID_SIZE
-fromchipsec.hal.uefi_commonimportop_stall,op_dispatch,op_terminate,op_mem_poll,op_unknown,get_3b_size,get_nvar_name,op_smbus_execute,script_width_formats
-fromchipsec.hal.uefi_commonimportS3BOOTSCRIPT_ENTRY,MAX_S3_BOOTSCRIPT_ENTRY_LENGTH,VARIABLE_STORE_FV_GUID,IS_VARIABLE_ATTRIBUTE,VARIABLE_DATA
-fromchipsec.hal.uefi_commonimportEFI_VARIABLE_BOOTSERVICE_ACCESS,EFI_VARIABLE_NON_VOLATILE,EFI_VARIABLE_RUNTIME_ACCESS,script_opcodes
-fromchipsec.hal.uefi_commonimportEFI_VARIABLE_HARDWARE_ERROR_RECORD,EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS,EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
-fromchipsec.hal.uefi_fvimportNextFwVolume,NextFwFile,EFI_FVB2_ERASE_POLARITY,EFI_FV_FILETYPE_RAW
-
-EfiTableType=Union['EFI_HDR_VSS','EFI_HDR_VSS_AUTH','EFI_HDR_VSS_APPLE',None]
-EfiVariableType=Tuple[int,bytes,EfiTableType,bytes,str,int]
-
-#
-# List of supported types of EFI NVRAM format (platform/vendor specific)
-#
-
-
-
[docs]classFWType:
- EFI_FW_TYPE_UEFI='uefi'
- EFI_FW_TYPE_UEFI_AUTH='uefi_auth'
-# EFI_FW_TYPE_WIN = 'win' # Windows 8 GetFirmwareEnvironmentVariable format
- EFI_FW_TYPE_VSS='vss'# NVRAM using format with '$VSS' signature
- EFI_FW_TYPE_VSS_AUTH='vss_auth'# NVRAM using format with '$VSS' signature with extra fields
- # See "A Tour Beyond BIOS Implementing UEFI Authenticated
- # Variables in SMM with EDKII"
- EFI_FW_TYPE_VSS2='vss2'
- EFI_FW_TYPE_VSS2_AUTH='vss2_auth'
- EFI_FW_TYPE_VSS_APPLE='vss_apple'
- EFI_FW_TYPE_NVAR='nvar'# 'NVAR' NVRAM format
- EFI_FW_TYPE_EVSA='evsa'# 'EVSA' NVRAM format
-
-
-fw_types:List[str]=[]
-foriin[tfortindir(FWType)ifnotcallable(getattr(FWType,t))]:
- ifnoti.startswith('__'):
- fw_types.append(getattr(FWType,i))
-
-
-NVRAM_ATTR_RT=1
-NVRAM_ATTR_DESC_ASCII=2
-NVRAM_ATTR_GUID=4
-NVRAM_ATTR_DATA=8
-NVRAM_ATTR_EXTHDR=0x10
-NVRAM_ATTR_AUTHWR=0x40
-NVRAM_ATTR_HER=0x20
-NVRAM_ATTR_VLD=0x80
-
-#
-# Known GUIDs of NVRAM stored in EFI firmware volumes, FS files etc. of various firmware implementations
-#
-ADDITIONAL_NV_STORE_GUID=UUID('00504624-8A59-4EEB-BD0F-6B36E96128E0')
-NVAR_NVRAM_FS_FILE=UUID("CEF5B9A3-476D-497F-9FDC-E98143E0422C")
-
-LENOVO_FS1_GUID=UUID("16B45DA2-7D70-4AEA-A58D-760E9ECB841D")
-LENOVO_FS2_GUID=UUID("E360BDBA-C3CE-46BE-8F37-B231E5CB9F35")
-
-EFI_PLATFORM_FS_GUIDS=[LENOVO_FS1_GUID,LENOVO_FS2_GUID]
-EFI_NVRAM_GUIDS=[VARIABLE_STORE_FV_GUID,ADDITIONAL_NV_STORE_GUID,NVAR_NVRAM_FS_FILE]
-
-#
-# This Variable header is defined by UEFI
-#
-
-#
-# Variable Store Status
-#
-# typedef enum {
-# EfiRaw,
-# EfiValid,
-# EfiInvalid,
-# EfiUnknown
-# } VARIABLE_STORE_STATUS;
-VARIABLE_STORE_STATUS_RAW=0
-VARIABLE_STORE_STATUS_VALID=1
-VARIABLE_STORE_STATUS_INVALID=2
-VARIABLE_STORE_STATUS_UNKNOWN=3
-
-#
-# Variable State flags
-#
-VAR_IN_DELETED_TRANSITION=0xfe# Variable is in obsolete transition
-VAR_DELETED=0xfd# Variable is obsolete
-VAR_ADDED=0x7f# Variable has been completely added
-
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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: Platform Hardware Security Assessment Framework
-#
-# -------------------------------------------------------------------------------
-
-"""
-UEFI image search auxillary functionality
-
-usage:
- >>> chipsec.hal.uefi_search.check_match_criteria(efi_module, match_criteria, self.logger)
-"""
-
-importre
-fromuuidimportUUID
-fromtypingimportDict,Callable,Optional,Any
-
-fromchipsecimportdefines
-fromchipsec.hal.spi_uefiimportEFI_SECTION
-fromchipsec.loggerimportlogger
-
-#
-# - EFI binaries are searched according to criteria defined by "match" rules.
-# - EFI binaries matching exclusion criteria defined by "exclude" rules are excluded from matching.
-#
-# Format of the matching rules (any field can be empty or missing):
-# - Individual rules are OR'ed
-# - criteria within a given rule are AND'ed
-#
-# Example:
-#
-# "UEFI_rootkitX": {
-# "description": "yet another UEFI implant X",
-# "match": {
-# "rktX_rule1" : { "guid": "12345678-XXXX-XXXX-XXXX-XXXXXXXXXXXX" },
-# "rktX_rule2" : { "name": "rootkitX.efi" }
-# }
-# }
-#
-# Above UEFI_rootkitX example results in a match if the following EFI binary is found:
-# - with GUID "12345678-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
-# OR
-# - with Name "rootkitX.efi"
-#
-#
-# "UEFI_vulnerabilityX": {
-# "description": "yet another UEFI vulnerability X",
-# "match": {
-# "vulnX_rule1": { "guid": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", "regexp": "IAMVULNERABLE" },
-# "vulnX_rule2": { "md5": "aabbccddeeffgghhiijjkkllmmnnoopp", "sha1": "aabbccddeeffgghhiijjkkllmmnnooppqqrrsstt" }
-# },
-# "exclude": {
-# "vulnX_patched": { "md5": "HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH", "sha1": "HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH" }
-# }
-# }
-#
-# Above UEFI_vulnerabilityX example results in a match if the following EFI binary is found:
-# - with GUID "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" AND contains a byte sequence matching regular expression "IAMVULNERABLE"
-# OR
-# - with MD5 hash "aabbccddeeffgghhiijjkkllmmnnoopp" AND SHA-1 hash "aabbccddeeffgghhiijjkkllmmnnooppqqrrsstt"
-# Unless it's a EFI binary:
-# - with MD5 hash "HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH" AND SHA-1 hash "HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH"
-#
-#
-# "UEFI_vulnerabilityY": {
-# "description": "Something else to be scared of!",
-# "match": {
-# "vulnY_rule1": {"guid": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee", "cpuid": "12345,abcde" }
-# }
-# }
-#
-# Above UEFI_vulnerabilityY example results in a match if the following EFI binary is found:
-# - with GUID "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee" AND if the binary is dumped from a live system, check's the system's CPUID to see if it matches one in the list "12345,abcde"
-#
-MATCH_NAME=0x1
-MATCH_GUID=(0x1<<1)
-MATCH_REGEXP=(0x1<<2)
-MATCH_HASH_MD5=(0x1<<3)
-MATCH_HASH_SHA1=(0x1<<4)
-MATCH_HASH_SHA256=(0x1<<5)
-MATCH_CPUID=(0x1<<6)
-
-
-
[docs]defcheck_match_criteria(efi:EFI_SECTION,criteria:Dict[str,Dict[str,Dict[str,str]]],_log:Callable,cpuid:Optional[str]=None)->bool:
- bfound=False
- if_logisNone:
- _log=logger()
- _log.log(f'[uefi] Checking {efi.name()}')
- forkincriteria.keys():
- entry=criteria[k]
- # Check if the EFI binary is a match
- if'match'inentry:
- bmatch=check_rules(efi,entry['match'],k,_log,cpuid=cpuid)
- ifbmatch:
- _log.log_important(f"found EFI binary matching '{k}'")
- if'description'inentry:
- _log.log(f" {entry['description']}")
- _log.log(str(efi))
- # Check if the matched binary should be excluded
- # There's no point in checking a binary against exclusions if it wasn't a match
- if'exclude'inentry:
- ifcheck_rules(efi,entry['exclude'],f'{k}.exclude',_log,cpuid=cpuid):
- _log.log_important(f"matched EFI binary is excluded from '{k}'. Skipping...")
- continue
- # we are here if the matched binary wasn't excluded
- # the binary is a final match if it matches either of search entries
- bfound=bfoundorbmatch
-
- returnbfound
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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
-#
-
-
-"""
-Access to virtual memory
-
-usage:
- >>> read_virtual_mem( 0xf0000, 0x100 )
- >>> write_virtual_mem( 0xf0000, 0x100, buffer )
- >>> write_virtual_mem_dowrd( 0xf0000, 0xdeadbeef )
- >>> read_virtual_mem_dowrd( 0xfed40000 )
-"""
-
-importstruct
-fromtypingimportTuple
-fromchipsec.loggerimportlogger,print_buffer_bytes
-fromchipsec.halimporthal_base
-
-
-
[docs]classVirtMemory(hal_base.HALBase):
- def__init__(self,cs):
- super(VirtMemory,self).__init__(cs)
- self.helper=cs.helper
-
- ####################################################################################
- #
- # virtual memory API using 64b virtual Address
- # (Same functions as below just using 64b PA instead of High and Low 32b parts of PA)
- #
- ####################################################################################
-
- # Reading virtual memory
-
-
[docs]defread_virtual_mem_dword(self,virt_address:int)->int:
- phys_address=self.va2pa(virt_address)
- out_buf=self.helper.read_phys_mem(phys_address,4)
- value=struct.unpack('=I',out_buf)[0]
- logger().log_hal(f'[mem] dword at VA = 0x{virt_address:016X}: 0x{value:08X}')
- returnvalue
-
-
[docs]defread_virtual_mem_word(self,virt_address:int)->int:
- phys_address=self.va2pa(virt_address)
- out_buf=self.helper.read_phys_mem(phys_address,2)
- value=struct.unpack('=H',out_buf)[0]
- logger().log_hal(f'[mem] word at VA = 0x{virt_address:016X}: 0x{value:04X}')
- returnvalue
-
-
[docs]defread_virtual_mem_byte(self,virt_address:int)->int:
- phys_address=self.va2pa(virt_address)
- out_buf=self.helper.read_phys_mem(phys_address,1)
- value=struct.unpack('=B',out_buf)[0]
- logger().log_hal(f'[mem] byte at VA = 0x{virt_address:016X}: 0x{value:02X}')
- returnvalue
-
- # Writing virtual memory
-
-
[docs]defwrite_virtual_mem(self,virt_address:int,length:int,buf:bytes)->int:
- logger().log_hal(f'[mem] buffer len = 0x{length:X} to VA = 0x{virt_address:016X}')
- iflogger().HAL:
- print_buffer_bytes(buf)
- phys_address=self.va2pa(virt_address)
- returnself.helper.write_phys_mem(phys_address,length,buf)
-
-
[docs]defwrite_virtual_mem_dword(self,virt_address:int,dword_value:int)->int:
- logger().log_hal(f'[mem] dword to VA = 0x{virt_address:016X} <- 0x{dword_value:08X}')
- phys_address=self.va2pa(virt_address)
- returnself.helper.write_phys_mem(phys_address,4,struct.pack('I',dword_value))
-
-
[docs]defwrite_virtual_mem_word(self,virt_address:int,word_value:int)->int:
- logger().log_hal(f'[mem] word to VA = 0x{virt_address:016X} <- 0x{word_value:04X}')
- phys_address=self.va2pa(virt_address)
- returnself.helper.write_phys_mem(phys_address,2,struct.pack('H',word_value))
-
-
[docs]defwrite_virtual_mem_byte(self,virt_address:int,byte_value:int)->int:
- logger().log_hal(f'[mem] byte to VA = 0x{virt_address:016X} <- 0x{byte_value:02X}')
- phys_address=self.va2pa(virt_address)
- returnself.helper.write_phys_mem(phys_address,1,struct.pack('B',byte_value))
-
- # Allocate virtual memory buffer
-
-
[docs]defalloc_virtual_mem(self,length:int,max_phys_address:int=0xFFFFFFFFFFFFFFFF)->Tuple[int,int]:
- (va,pa)=self.helper.alloc_phys_mem(length,max_phys_address)
- logger().log_hal(f'[mem] Allocated: PA = 0x{pa:016X}, VA = 0x{va:016X}')
- return(va,pa)
-
-
[docs]defva2pa(self,va:int)->int:
- (pa,error_code)=self.helper.va2pa(va)
- iferror_code:
- logger().log_hal(f'[mem] Looks like VA (0x{va:016X}) not mapped')
- returnva
- logger().log_hal(f'[mem] VA (0x{va:016X}) -> PA (0x{pa:016X})')
- returnpa
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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
-#
-
-"""
-VMM specific functionality
-1. Hypervisor hypercall interfaces
-2. Second-level Address Translation (SLAT)
-3. VirtIO devices
-4. ...
-
-"""
-
-importstruct
-
-fromtypingimportAnyStr,Dict,List,Optional,Tuple
-fromchipsec.loggerimportlogger,pretty_print_hex_buffer
-importchipsec.hal.pcidb
-
-
-
[docs]definit(self)->None:
- (self.membuf0_va,self.membuf0_pa)=self.cs.mem.alloc_physical_mem(0x2000,0xFFFFFFFFFFFFFFFF)
- (self.membuf1_va,self.membuf1_pa)=(self.membuf0_va+0x1000,self.membuf0_pa+0x1000)
- ifself.membuf0_va==0:
- logger().log("[vmm] Could not allocate memory!")
- raiseException("[vmm] Could not allocate memory!")
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2019-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
-#
-
-fromabcimportABC,abstractmethod
-fromtypingimportDict,List,Tuple,Optional,TYPE_CHECKING
-ifTYPE_CHECKING:
- fromchipsec.library.typesimportEfiVariableType
- fromctypesimportArray
-
-# Base class for the helpers
-
-
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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
-#
-
-
-"""
-Intel DFx Abstraction Layer (DAL) helper
-
-From the Intel(R) DFx Abstraction Layer Python* Command Line Interface User Guide
-
-"""
-
-importstruct
-
-fromchipsec.loggerimportlogger
-try:
- importitpii
-except:
- pass
-fromctypesimportc_char
-fromtypingimportTuple
-fromchipsec.helper.basehelperimportHelper
-fromchipsec.exceptionsimportDALHelperError,UnimplementedAPIError
-
-
-
[docs]classDALHelper(Helper):
- def__init__(self):
- super(DALHelper,self).__init__()
- self.base=itpii.baseaccess()
- self.is_system_halted=True
- logger().log_debug('[helper] DAL Helper')
- ifnotlen(self.base.threads):
- logger().log('[helper] No threads detected! DAL Helper will fail to load!')
- elifself.base.threads[self.find_thread()].cv.isrunning:
- self.is_system_halted=False
- self.base.halt()
- self.os_system='(Via Intel DAL)'
- self.os_release='(N/A)'
- self.os_version=self.dal_version()
- self.os_machine=self.target_machine()
- self.name="DALHelper"
-
- def__del__(self):
- ifnotlen(self.base.threads):
- logger().log('[helper] No threads detected!')
- elifnotself.is_system_halted:
- logger().log('[helper] Threads are halted')
- else:
- self.base.go()
- logger().log('[helper] Threads are running')
-
-
-###############################################################################################
-# Driver/service management functions
-###############################################################################################
-
-
[docs]defcreate(self,start_driver:bool)->bool:
- logger().log_debug('[helper] DAL Helper created')
- returnTrue
[docs]defdelete(self)->bool:
- logger().log_debug('[helper] DAL Helper deleted')
- returnTrue
-
-
-###############################################################################################
-# Functions to get information about the remote target
-###############################################################################################
-
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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: Platform Hardware Security Assessment Framework
-#
-# -------------------------------------------------------------------------------
-
-"""
-On UEFI use the efi package functions
-"""
-
-importstruct
-importsys
-importuuid
-importos
-importedk2# Python 3.6.8 on UEFI
-
-fromtypingimportDict,List,Optional,Tuple,TYPE_CHECKING
-ifTYPE_CHECKING:
- fromchipsec.library.typesimportEfiVariableType
-fromchipsec.loggerimportlogger
-fromchipsec.helper.oshelperimportget_tools_path
-fromchipsec.helper.basehelperimportHelper
-fromchipsec.exceptionsimportUnimplementedAPIError
-
-
-_tools={
-}
-
-
[docs]defstart(self)->bool:
- # The driver is part of the modified version of edk2.
- # It is always considered as loaded.
- self.driver_loaded=True
- logger().log_debug('[helper] UEFI Helper started/loaded')
- returnTrue
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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
-#
-
-"""
-Linux helper
-"""
-
-importarray
-importctypes
-importerrno
-importfcntl
-importfnmatch
-importmmap
-importos
-importplatform
-importresource
-importstruct
-importsubprocess
-importsys
-fromtypingimportDict,List,Optional,Tuple,Iterable,TYPE_CHECKING
-ifTYPE_CHECKING:
- fromchipsec.library.typesimportEfiVariableType
-fromchipsecimportdefines
-fromchipsec.helper.oshelperimportget_tools_path
-fromchipsec.exceptionsimportOsHelperError,UnimplementedAPIError
-fromchipsec.helper.basehelperimportHelper
-fromchipsec.loggerimportlogger
-importchipsec.file
-fromchipsec.hal.uefi_commonimportEFI_VARIABLE_NON_VOLATILE,EFI_VARIABLE_BOOTSERVICE_ACCESS,EFI_VARIABLE_RUNTIME_ACCESS
-fromchipsec.hal.uefi_commonimportEFI_VARIABLE_HARDWARE_ERROR_RECORD,EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
-fromchipsec.hal.uefi_commonimportEFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS,EFI_VARIABLE_APPEND_WRITE
-
-MSGBUS_MDR_IN_MASK=0x1
-MSGBUS_MDR_OUT_MASK=0x2
-
-IOCTL_BASE=0x0
-IOCTL_RDIO=0x1
-IOCTL_WRIO=0x2
-IOCTL_RDPCI=0x3
-IOCTL_WRPCI=0x4
-IOCTL_RDMSR=0x5
-IOCTL_WRMSR=0x6
-IOCTL_CPUID=0x7
-IOCTL_GET_CPU_DESCRIPTOR_TABLE=0x8
-IOCTL_HYPERCALL=0x9
-IOCTL_SWSMI=0xA
-IOCTL_LOAD_UCODE_PATCH=0xB
-IOCTL_ALLOC_PHYSMEM=0xC
-IOCTL_GET_EFIVAR=0xD
-IOCTL_SET_EFIVAR=0xE
-IOCTL_RDCR=0x10
-IOCTL_WRCR=0x11
-IOCTL_RDMMIO=0x12
-IOCTL_WRMMIO=0x13
-IOCTL_VA2PA=0x14
-IOCTL_MSGBUS_SEND_MESSAGE=0x15
-IOCTL_FREE_PHYSMEM=0x16
-
-_tools={}
-
-
[docs]defdelete(self)->bool:
- logger().log_debug("[helper] Linux Helper deleted")
- returnTrue
-
-
[docs]definit(self)->None:
- x64=Trueifsys.maxsize>2**32elseFalse
- self._pack='Q'ifx64else'I'
-
- estr="Unable to open chipsec device. Did you run as root/sudo and load the driver?\n{}"
- try:
- # Do not buffer access to physical memory...
- self.dev_fh=open(self.DEVICE_NAME,"rb+",buffering=0)
- self.driver_loaded=True
- exceptIOErrorase:
- raiseOsHelperError(estr.format(str(e)),e.errno)
- exceptBaseExceptionasbe:
- raiseOsHelperError(estr.format(str(be)),errno.ENXIO)
- self._ioctl_base=self.compute_ioctlbase()
-
- # code taken from /include/uapi/asm-generic/ioctl.h
- # by default itype is 'C' see drivers/linux/include/chipsec.h
- # currently all chipsec ioctl functions are _IOWR
- # currently all size are pointer
-
[docs]defcompute_ioctlbase(self,itype:str='C')->int:
- # define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
- # define _IOC(dir,type,nr,size) \
- # (((dir) << _IOC_DIRSHIFT) | \
- # ((type) << _IOC_TYPESHIFT) | \
- # ((nr) << _IOC_NRSHIFT) | \
- # ((size) << _IOC_SIZESHIFT))
- # IOC_READ | _IOC_WRITE is 3
- # default _IOC_DIRSHIFT is 30
- # default _IOC_TYPESHIFT is 8
- # nr will be 0
- # _IOC_SIZESHIFT is 16
- return(3<<30)|(ord(itype)<<8)|(struct.calcsize(self._pack)<<16)
-
-###############################################################################################
-# Actual API functions to access HW resources
-###############################################################################################
-
-
[docs]defva2pa(self,va:int)->Tuple[Optional[int],int]:
- error_code=0
-
- in_buf=struct.pack(self._pack,va)
- try:
- out_buf=self.ioctl(IOCTL_VA2PA,in_buf)
- pa=struct.unpack(self._pack,out_buf)[0]
- exceptIOErroraserr:
- iflogger().DEBUG:
- logger().log_error(f'[helper] Error in va2pa: getting PA for VA 0x{va:016X} failed with IOError: {err.strerror}')
- return(None,err.errno)
-
- # Check if PA > max physical address
- max_pa=self.cpuid(0x80000008,0x0)[0]&0xFF
- ifpa>1<<max_pa:
- iflogger().DEBUG:
- logger().log_error(f'[helper] Error in va2pa: PA higher that max physical address: VA (0x{va:016X}) -> PA (0x{pa:016X})')
- error_code=1
- return(pa,error_code)
-
-
[docs]defread_pci_reg(self,bus:int,device:int,function:int,offset:int,size:int=4)->int:
- _PCI_DOM=0# Change PCI domain, if there is more than one.
- d=struct.pack(f'5{self._pack}',((_PCI_DOM<<16)|bus),((device<<16)|function),offset,size,0)
- try:
- ret=self.ioctl(IOCTL_RDPCI,d)
- exceptIOError:
- iflogger().DEBUG:
- logger().log_error("IOError\n")
- return0
- x=struct.unpack(f'5{self._pack}',ret)
- returnx[4]
-
-
[docs]defwrite_pci_reg(self,bus:int,device:int,function:int,offset:int,value:int,size:int=4)->int:
- _PCI_DOM=0# Change PCI domain, if there is more than one.
- d=struct.pack(f'5{self._pack}',((_PCI_DOM<<16)|bus),((device<<16)|function),offset,size,value)
- try:
- ret=self.ioctl(IOCTL_WRPCI,d)
- exceptIOError:
- iflogger().DEBUG:
- logger().log_error("IOError\n")
- return0
- x=struct.unpack(f'5{self._pack}',ret)
- returnx[4]
-# -*- coding: utf-8 -*-
-# Copyright (c) 2020 Intel Corporation
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# This file incorporates work covered by the following copyright and
-# permission notice:
-#
-# Copyright (c) 2014 Anders Høst
-# Copyright (c) 2018 Anders Høst
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy of
-# this software and associated documentation files (the "Software"), to deal in
-# the Software without restriction, including without limitation the rights to
-# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-# the Software, and to permit persons to whom the Software is furnished to do so,
-# subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in all
-# copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
-importmmap
-importplatform
-fromctypesimportCFUNCTYPE,POINTER,Structure,addressof,c_uint32,c_void_p,sizeof
-fromtypingimportCallable,Generator,Tuple
-
-# Posix x86_64:
-# Three first call registers : RDI, RSI, RDX
-# Volatile registers : RAX, RCX, RDX, RSI, RDI, R8-11
-
-# cdecl 32 bit:
-# Three first call registers : Stack (%esp)
-# Volatile registers : EAX, ECX, EDX
-
-_POSIX_64_OPC=bytes((
- 0x53,# push %rbx
- 0x89,0xf0,# mov %esi,%eax
- 0x89,0xd1,# mov %edx,%ecx
- 0x0f,0xa2,# cpuid
- 0x89,0x07,# mov %eax,(%rdi)
- 0x89,0x5f,0x04,# mov %ebx,0x4(%rdi)
- 0x89,0x4f,0x08,# mov %ecx,0x8(%rdi)
- 0x89,0x57,0x0c,# mov %edx,0xc(%rdi)
- 0x5b,# pop %rbx
- 0xc3# retq
-))
-
-_CDECL_32_OPC=bytes((
- 0x53,# push %ebx
- 0x57,# push %edi
- 0x8b,0x7c,0x24,0x0c,# mov 0xc(%esp),%edi
- 0x8b,0x44,0x24,0x10,# mov 0x10(%esp),%eax
- 0x8b,0x4c,0x24,0x14,# mov 0x14(%esp),%ecx
- 0x0f,0xa2,# cpuid
- 0x89,0x07,# mov %eax,(%edi)
- 0x89,0x5f,0x04,# mov %ebx,0x4(%edi)
- 0x89,0x4f,0x08,# mov %ecx,0x8(%edi)
- 0x89,0x57,0x0c,# mov %edx,0xc(%edi)
- 0x5f,# pop %edi
- 0x5b,# pop %ebx
- 0xc3# ret
-))
-
-is_64bit=sizeof(c_void_p)==8
-
-
-
Source code for chipsec.helper.linuxnative.legacy_pci
-# -*- coding: utf-8 -*-
-# # Copyright (c) 2020 Intel Corporation
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# This file incorporates work covered by the following copyright and
-# permission notice:
-#
-# Copyright (c) 2014 Anders Høst
-# Copyright (c) 2018 Anders Høst
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy of
-# this software and associated documentation files (the "Software"), to deal in
-# the Software without restriction, including without limitation the rights to
-# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-# the Software, and to permit persons to whom the Software is furnished to do so,
-# subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in all
-# copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
-importmmap
-fromctypesimportCDLL,CFUNCTYPE,addressof,c_uint16,c_uint32,c_void_p,get_errno
-fromtypingimportCallable
-
-fromchipsec.exceptionsimportOsHelperError
-
-IN_PORT=bytes((
- 0x55,# push %rbp
- 0x48,0x89,0xe5,# mov %rsp,%rbp
- 0x89,0xf8,# mov %edi,%eax
- 0x66,0x89,0x45,0xec,# mov %ax,-0x14(%rbp)
- 0x0f,0xb7,0x45,0xec,# movzwl -0x14(%rbp),%eax
- 0x89,0xc2,# mov %eax,%edx
- 0xed,# in (%dx),%eax
- 0x89,0x45,0xfc,# mov %eax,-0x4(%rbp)
- 0x8b,0x45,0xfc,# mov -0x4(%rbp),%eax
- 0x5d,# pop %rbp
- 0xc3,# retq
-))
-
-
-OUT_PORT=bytes((
- 0x55,# push %rbp
- 0x48,0x89,0xe5,# mov %rsp,%rbp
- 0x89,0x7d,0xfc,# mov %edi,-0x4(%rbp)
- 0x89,0xf0,# mov %esi,%eax
- 0x66,0x89,0x45,0xf8,# mov %ax,-0x8(%rbp)
- 0x8b,0x45,0xfc,# mov -0x4(%rbp),%eax
- 0x0f,0xb7,0x55,0xf8,# movzwl -0x8(%rbp),%edx
- 0xef,# out %eax,(%dx)
- 0x90,# nop
- 0x5d,# pop %rbp
- 0xc3,# retq
-))
-
-
-
[docs]classPorts:
- # Use a unique Ports instance, to avoid allocating memory mappings every time it is used
- instance=None
-
- def__init__(self)->None:
- clib=CDLL("libc.so.6",use_errno=True)
- ifclib.iopl(3)==-1:
- raiseOsHelperError("Unable to use I/O ports using iopl",get_errno())
-
- self.inl_addr=mmap.mmap(-1,mmap.PAGESIZE,flags=mmap.MAP_PRIVATE,prot=mmap.PROT_READ|mmap.PROT_WRITE|mmap.PROT_EXEC)
- self.inl_addr.write(IN_PORT)
- in_func_type=CFUNCTYPE(c_uint32,c_uint16)
- in_fp=c_void_p.from_buffer(self.inl_addr)
- self.inl_ptr:Callable[[int],int]=in_func_type(addressof(in_fp))
-
- self.outl_addr=mmap.mmap(-1,mmap.PAGESIZE,flags=mmap.MAP_PRIVATE,prot=mmap.PROT_READ|mmap.PROT_WRITE|mmap.PROT_EXEC)
- self.outl_addr.write(OUT_PORT)
- out_func_type=CFUNCTYPE(None,c_uint32,c_uint16)
- out_fp=c_void_p.from_buffer(self.outl_addr)
- self.outl_ptr:Callable[[int,int],None]=out_func_type(addressof(out_fp))
-
-
Source code for chipsec.helper.linuxnative.linuxnativehelper
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2023, 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
-#
-
-"""
-Native Linux helper
-"""
-
-importmmap
-importos
-importplatform
-importresource
-importstruct
-importsys
-fromtypingimportOptional,Tuple
-
-fromchipsecimportdefines
-fromchipsec.exceptionsimportOsHelperError
-fromchipsec.helper.basehelperimportHelper
-fromchipsec.helper.linuxnative.cpuidimportCPUID
-fromchipsec.helper.linuxnative.legacy_pciimportLegacyPci
-fromchipsec.loggerimportlogger
-
-
-
[docs]classMemoryMapping(mmap.mmap):
- """Memory mapping based on Python's mmap.
- This subclass keeps tracks of the start and end of the mapping.
- """
-
- def__init__(self,fileno,length,flags,prot,offset):
- self.start=offset
- self.end=offset+length
- super().__init__()
-
-
-
[docs]classLinuxNativeHelper(Helper):
-
- DEV_MEM="/dev/mem"
- DEV_PORT="/dev/port"
-
- def__init__(self):
- super(LinuxNativeHelper,self).__init__()
- self.os_system=platform.system()
- self.os_release=platform.release()
- self.os_version=platform.version()
- self.os_machine=platform.machine()
- self.os_uname=platform.uname()
- self.name="LinuxNativeHelper"
- self.dev_fh=None
- self.dev_mem=None
- self.dev_port=None
- self.dev_msr=None
-
- # A list of all the mappings allocated via map_io_space. When using
- # read/write MMIO, if the region is already mapped in the process's
- # memory, simply read/write from there.
- self.mappings=[]
-
-###############################################################################################
-# Driver/service management functions
-###############################################################################################
-
[docs]defcreate(self)->bool:
- logger().log_debug("[helper] Linux Helper created")
- returnTrue
-
-
[docs]defstart(self)->bool:
- self.init()
- logger().log_debug("[helper] Linux Helper started/loaded")
- returnTrue
-
-
[docs]defstop(self)->bool:
- self.close()
- logger().log_debug("[helper] Linux Helper stopped/unloaded")
- returnTrue
-
-
[docs]defdelete(self)->bool:
- logger().log_debug("[helper] Linux Helper deleted")
- returnTrue
[docs]defdevmem_available(self)->bool:
- """Check if /dev/mem is usable.
- In case the driver is not loaded, we might be able to perform the
- requested operation via /dev/mem. Returns True if /dev/mem is
- accessible.
- """
- ifself.dev_mem:
- returnTrue
-
- try:
- self.dev_mem=os.open(self.DEV_MEM,os.O_RDWR)
- returnTrue
- exceptIOErroraserr:
- raiseOsHelperError("Unable to open /dev/mem.\n"
- "This command requires access to /dev/mem.\n"
- "Are you running this command as root?\n"
- f"{str(err)}",err.errno)
-
-
[docs]defdevport_available(self)->bool:
- """Check if /dev/port is usable.
- In case the driver is not loaded, we might be able to perform the
- requested operation via /dev/port. Returns True if /dev/port is
- accessible.
- """
- ifself.dev_port:
- returnTrue
-
- try:
- self.dev_port=os.open(self.DEV_PORT,os.O_RDWR)
- returnTrue
- exceptIOErroraserr:
- raiseOsHelperError("Unable to open /dev/port.\n"
- "This command requires access to /dev/port.\n"
- "Are you running this command as root?\n"
- f"{str(err)}",err.errno)
-
-
[docs]defdevmsr_available(self)->bool:
- """Check if /dev/cpu/CPUNUM/msr is usable.
- In case the driver is not loaded, we might be able to perform the
- requested operation via /dev/cpu/CPUNUM/msr. This requires loading
- the (more standard) msr driver. Returns True if /dev/cpu/CPUNUM/msr
- is accessible.
- """
- ifself.dev_msr:
- returnTrue
-
- try:
- self.dev_msr={}
- ifnotos.path.exists("/dev/cpu/0/msr"):
- os.system("modprobe msr")
- forcpuinos.listdir("/dev/cpu"):
- logger().log_debug(f"found cpu = {str(cpu)}")
- ifcpu.isdigit():
- cpu=int(cpu)
- self.dev_msr[cpu]=os.open(f"/dev/cpu/{str(cpu)}/msr",os.O_RDWR)
- logger().log_debug(f"Added dev_msr {str(cpu)}")
- returnTrue
- exceptIOErroraserr:
- raiseOsHelperError("Unable to open /dev/cpu/CPUNUM/msr.\n"
- "This command requires access to /dev/cpu/CPUNUM/msr.\n"
- "Are you running this command as root?\n"
- "Do you have the msr kernel module installed?\n"
- f"{str(err)}",err.errno)
-
-###############################################################################################
-# Actual API functions to access HW resources
-###############################################################################################
-
-
[docs]defmemory_mapping(self,base:int,size:int)->Optional[MemoryMapping]:
- """Returns the mmap region that fully encompasses this area.
- Returns None if no region matches.
- """
- forregioninself.mappings:
- ifregion.start<=baseandregion.end>=base+size:
- returnregion
- returnNone
-
-
[docs]defmap_io_space(self,base:int,size:int,cache_type:int)->None:
- """Map to memory a specific region."""
- ifself.devmem_available()andnotself.memory_mapping(base,size):
- logger().log_debug(f"[helper] Mapping 0x{base:x} to memory")
- length=max(size,resource.getpagesize())
- page_aligned_base=base-(base%resource.getpagesize())
- mapping=MemoryMapping(self.dev_mem,length,mmap.MAP_SHARED,
- mmap.PROT_READ|mmap.PROT_WRITE,
- offset=page_aligned_base)
- self.mappings.append(mapping)
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2023, 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
-#
-
-fromchipsec.exceptionsimportUnimplementedAPIError
-fromchipsec.helper.basehelperimportHelper
-fromtypingimportDict,List,Tuple,Optional,TYPE_CHECKING
-ifTYPE_CHECKING:
- fromchipsec.library.typesimportEfiVariableType
- fromctypesimportArray
-
-# Base class for the helpers
-
-
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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
-#
-
-"""
-Abstracts support for various OS/environments, wrapper around platform specific code that invokes kernel driver
-"""
-
-importos
-importerrno
-importimportlib
-importplatform
-importtraceback
-importsys
-fromctypesimportArray
-fromtypingimportTuple,List,Dict,Optional,AnyStr,Any,TYPE_CHECKING
-ifTYPE_CHECKING:
- fromchipsec.library.typesimportEfiVariableType
-fromchipsec.fileimportget_main_dir,TOOLS_DIR
-fromchipsec.loggerimportlogger
-fromchipsec.helper.basehelperimportHelper
-fromchipsec.helper.nonehelperimportNoneHelper
-fromchipsec.exceptionsimportUnimplementedAPIError,OsHelperError
-
-
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2023, 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: Platform Security Assessment Framework
-# Copyright (c) 2023, 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
-#
-
-fromtypingimportOptional
-
-BIT0=0x0001
-BIT1=0x0002
-BIT2=0x0004
-BIT3=0x0008
-BIT4=0x0010
-BIT5=0x0020
-BIT6=0x0040
-BIT7=0x0080
-BIT8=0x0100
-BIT9=0x0200
-BIT10=0x0400
-BIT11=0x0800
-BIT12=0x1000
-BIT13=0x2000
-BIT14=0x4000
-BIT15=0x8000
-BIT16=0x00010000
-BIT17=0x00020000
-BIT18=0x00040000
-BIT19=0x00080000
-BIT20=0x00100000
-BIT21=0x00200000
-BIT22=0x00400000
-BIT23=0x00800000
-BIT24=0x01000000
-BIT25=0x02000000
-BIT26=0x04000000
-BIT27=0x08000000
-BIT28=0x10000000
-BIT29=0x20000000
-BIT30=0x40000000
-BIT31=0x80000000
-BIT32=0x100000000
-BIT33=0x200000000
-BIT34=0x400000000
-BIT35=0x800000000
-BIT36=0x1000000000
-BIT37=0x2000000000
-BIT38=0x4000000000
-BIT39=0x8000000000
-BIT40=0x10000000000
-BIT41=0x20000000000
-BIT42=0x40000000000
-BIT43=0x80000000000
-BIT44=0x100000000000
-BIT45=0x200000000000
-BIT46=0x400000000000
-BIT47=0x800000000000
-BIT48=0x1000000000000
-BIT49=0x2000000000000
-BIT50=0x4000000000000
-BIT51=0x8000000000000
-BIT52=0x10000000000000
-BIT53=0x20000000000000
-BIT54=0x40000000000000
-BIT55=0x80000000000000
-BIT56=0x100000000000000
-BIT57=0x200000000000000
-BIT58=0x400000000000000
-BIT59=0x800000000000000
-BIT60=0x1000000000000000
-BIT61=0x2000000000000000
-BIT62=0x4000000000000000
-BIT63=0x8000000000000000
-
-
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2023, 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
-#
-
-importstring
-fromtimeimportstrftime
-fromtypingimportAnyStr,Iterable
-
-
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2023, 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
-#
-
-importstruct
-fromtypingimportDict
-
-
-
[docs]defpack1(value:int,size:int)->bytes:
- """Shortcut to pack a single value into a string based on its size."""
- returnstruct.pack(SIZE2FORMAT[size],value)
-
-
-
[docs]defunpack1(string:bytes,size:int)->int:
- """Shortcut to unpack a single value from a string based on its size."""
- returnstruct.unpack(SIZE2FORMAT[size],string)[0]
Source code for chipsec.modules.common.bios_kbrd_buffer
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-2020, 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
-#
-
-
-"""
-Checks for exposure of pre-boot passwords (BIOS/HDD/pre-bot authentication SW) in the BIOS keyboard buffer.
-
-Reference:
- - DEFCON 16: `Bypassing Pre-boot Authentication Passwords by Instrumenting the BIOS Keyboard Buffer <https://www.defcon.org/images/defcon-16/dc16-presentations/brossard/defcon-16-brossard-wp.pdf>`_ by Jonathan Brossard
-
-Usage:
- ``chipsec_main -m common.bios_kbrd_buffer``
-
-Examples:
- >>> chipsec_main.py -m common.bios_kbrd_buffer
-
-"""
-
-fromchipsec.module_commonimportBaseModule,ModuleResult,MTAG_BIOS
-fromchipsec.loggerimportprint_buffer_bytes
-fromtypingimportList
-
-TAGS=[MTAG_BIOS]
-
-COMMON_FILL_PTRN="".join([f'{(chr(x+0x1E)):1}'forxinrange(32)])
-
-
-
[docs]defcheck_BIOS_keyboard_buffer(self)->int:
- kbrd_buf_head=self.cs.mem.read_physical_mem_dword(0x41A)&0x000000FF
- kbrd_buf_tail=self.cs.mem.read_physical_mem_dword(0x41C)&0x000000FF
- self.logger.log(f"[*] Keyboard buffer head pointer = 0x{kbrd_buf_head:X} (at 0x41A), tail pointer = 0x{kbrd_buf_tail:X} (at 0x41C)")
- bios_kbrd_buf=self.cs.mem.read_physical_mem(0x41E,32)
- self.logger.log("[*] Keyboard buffer contents (at 0x41E):")
- print_buffer_bytes(bios_kbrd_buf)
- bios_kbrd_buf=bios_kbrd_buf.decode('latin_1')
-
- has_contents=False
-
- ifCOMMON_FILL_PTRN==bios_kbrd_buf:
- self.logger.log_good("Keyboard buffer is filled with common fill pattern")
- self.rc_res.setStatusBit(self.rc_res.status.SUCCESS)
- returnself.rc_res.getReturnCode(ModuleResult.PASSED)
-
- forxinbios_kbrd_buf:
- if("\x00"!=x)and("\x20"!=x):
- has_contents=True
- break
-
- if(0x1E<kbrd_buf_tail)and(kbrd_buf_tail<=0x1E+32):
- self.logger.log_bad(f"Keyboard buffer tail points inside the buffer (= 0x{kbrd_buf_tail:X})")
- self.logger.log(f" It may potentially expose lengths of pre-boot passwords. Was your password {(kbrd_buf_tail+2-0x1E)//2:d} characters long?")
-
- self.logger.log("[*] Checking contents of the keyboard buffer..\n")
-
- ifhas_contents:
- self.logger.log_warning("Keyboard buffer is not empty. The test cannot determine conclusively if it contains pre-boot passwords.")
- self.logger.log(" - The contents might have not been cleared by pre-boot firmware or overwritten with garbage.")
- self.logger.log(" - Visually inspect the contents of keyboard buffer for pre-boot passwords (BIOS, HDD, full-disk encryption).")
- else:
- self.logger.log_passed("Keyboard buffer looks empty. Pre-boot passwords don't seem to be exposed")
-
- ifhas_contents:
- self.rc_res.setStatusBit(self.rc_res.status.POTENTIALLY_VULNERABLE)
- returnself.rc_res.getReturnCode(ModuleResult.WARNING)
- else:
- self.rc_res.setStatusBit(self.rc_res.status.SUCCESS)
- returnself.rc_res.getReturnCode(ModuleResult.PASSED)
-
- # --------------------------------------------------------------------------
- # run( module_argv )
- # Required function: run here all tests from this module
- # --------------------------------------------------------------------------
-
[docs]defrun(self,module_argv:List[str])->int:
- self.logger.start_test("Pre-boot Passwords in the BIOS Keyboard Buffer")
- self.res=self.check_BIOS_keyboard_buffer()
- returnself.res
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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
-#
-
-
-"""
-The module checks that SMI events configuration is locked down
-- Global SMI Enable/SMI Lock
-- TCO SMI Enable/TCO Lock
-
-References:
- - `Setup for Failure: Defeating SecureBoot <http://syscan.org/index.php/download/get/6e597f6067493dd581eed737146f3afb/SyScan2014_CoreyKallenberg_SetupforFailureDefeatingSecureBoot.zip>`_ by Corey Kallenberg, Xeno Kovah, John Butterworth, Sam Cornwell
- - `Summary of Attacks 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>`_
-
-Usage:
- ``chipsec_main -m common.bios_smi``
-
-Examples:
- >>> chipsec_main.py -m common.bios_smi
-
-Registers used:
- - SmmBiosWriteProtection (Control)
- - TCOSMILock (Control)
- - SMILock (Control)
- - BiosWriteEnable (Control)
-
-"""
-
-fromchipsec.module_commonimportBaseModule,ModuleResult,MTAG_BIOS,MTAG_SMM
-fromtypingimportList
-
-
-TAGS=[MTAG_BIOS,MTAG_SMM]
-
-
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-2020, 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
-#
-
-
-"""
-Checks for BIOS Interface Lock including Top Swap Mode
-
-References:
- - `BIOS Boot Hijacking and VMware Vulnerabilities Digging <http://powerofcommunity.net/poc2007/sunbing.pdf>`_ by Bing Sun
-
-Usage:
- ``chipsec_main -m common.bios_ts``
-
-Examples:
- >>> chipsec_main.py -m common.bios_ts
-
-Registers used:
- - BiosInterfaceLockDown (control)
- - TopSwapStatus (control)
- - TopSwap (control)
-
-"""
-
-fromchipsec.module_commonimportBaseModule,ModuleResult,MTAG_BIOS
-fromtypingimportList
-TAGS=[MTAG_BIOS]
-
-
-
[docs]defis_supported(self)->bool:
- ifself.cs.is_control_defined('BiosInterfaceLockDown'):
- returnTrue
- self.logger.log_important('BiosInterfaceLockDown control not defined for platform. Skipping module.')
- self.rc_res.setStatusBit(self.rc_res.status.NOT_APPLICABLE)
- self.res=self.rc_res.getReturnCode(ModuleResult.NOTAPPLICABLE)
- returnFalse
-
-
[docs]defcheck_bios_iface_lock(self)->int:
- bild=self.cs.get_control('BiosInterfaceLockDown')
- self.logger.log(f"[*] BiosInterfaceLockDown (BILD) control = {bild:d}")
-
- ifself.cs.is_control_defined('TopSwapStatus'):
- ifself.cs.is_control_all_ffs('TopSwapStatus'):
- self.logger.log("[*] BIOS Top Swap mode: can't determine status.")
- self.logger.log_verbose('TopSwapStatus read returned all 0xFs.')
- else:
- tss=self.cs.get_control('TopSwapStatus')
- self.logger.log(f"[*] BIOS Top Swap mode is {'enabled'if(1==tss)else'disabled'} (TSS = {tss:d})")
-
- ifself.cs.is_control_defined('TopSwap'):
- ifself.cs.is_control_all_ffs('TopSwap'):
- self.logger.log("[*] RTC Top Swap control (TS): can't determine status.")
- self.logger.log_verbose('TopSwap read returned all 0xFs.')
- else:
- ts=self.cs.get_control('TopSwap')
- self.logger.log(f"[*] RTC TopSwap control (TS) = {ts:x}")
-
- ifbild==0:
- res=ModuleResult.FAILED
- self.rc_res.setStatusBit(self.rc_res.status.LOCKS)
- self.logger.log_failed("BIOS Interface is not locked (including Top Swap Mode)")
- else:
- res=ModuleResult.PASSED
- self.logger.log_passed("BIOS Interface is locked (including Top Swap Mode)")
-
- returnself.rc_res.getReturnCode(res)
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-2020, 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
-#
-
-
-"""
-The BIOS region in flash can be protected either using SMM-based protection or using configuration in the SPI controller. However, the SPI controller configuration is set once and locked, which would prevent writes later.
-
-This module checks both mechanisms. In order to pass this test using SPI controller configuration, the SPI Protected Range registers (PR0-4) will need to cover the entire BIOS region.
-Often, if this configuration is used at all, it is used only to protect part of the BIOS region (usually the boot block).
-If other important data (eg. NVRAM) is not protected, however, some vulnerabilities may be possible.
-
-`A Tale of One Software Bypass of Windows 8 Secure Boot <http://www.c7zero.info/stuff/Windows8SecureBoot_Bulygin-Furtak-Bazhniuk_BHUSA2013.pdf>`_
-In a system where certain BIOS data was not protected, malware may be able to write to the Platform Key stored on the flash, thereby disabling secure boot.
-
-SMM based write protection is controlled from the BIOS Control Register. When the BIOS Write Protect Disable bit is set (sometimes called BIOSWE or BIOS Write Enable), then writes are allowed. When cleared, it can also be locked with the BIOS Lock Enable (BLE) bit. When locked, attempts to change the WPD bit will result in generation of an SMI. This way, the SMI handler can decide whether to perform the write.
-
-As demonstrated in the `Speed Racer <https://bromiumlabs.files.wordpress.com/2015/01/speed_racer_whitepaper.pdf>`_ issue, a race condition may exist between the outstanding write and processing of the SMI that is generated. For this reason, the EISS bit (sometimes called SMM_BWP or SMM BIOS Write Protection) must be set to ensure that only SMM can write to the SPI flash.
-
-References:
- - `A Tale of One Software Bypass of Windows 8 Secure Boot <http://www.c7zero.info/stuff/Windows8SecureBoot_Bulygin-Furtak-Bazhniuk_BHUSA2013.pdf>`_
- - `Speed Racer <https://bromiumlabs.files.wordpress.com/2015/01/speed_racer_whitepaper.pdf>`_
-
-Usage:
- ``chipsec_main -m common.bios_wp``
-
-Examples:
- >>> chipsec_main.py -m common.bios_wp
-
-Registers used: (n = 0,1,2,3,4)
- - BiosLockEnable (Control)
- - BiosWriteEnable (Control)
- - SmmBiosWriteProtection (Control)
- - PRn.PRB
- - PRn.RPE
- - PRn.PRL
- - PRn.WPE
-
-.. note::
- - Module will fail if SMM-based protection is not correctly configured and SPI protected ranges (PR registers) do not protect the entire BIOS region.
-
-"""
-
-fromchipsec.module_commonimportBaseModule,ModuleResult,MTAG_BIOS
-fromchipsec.hal.spiimportBIOS,SPI
-fromtypingimportList
-
-
-TAGS=[MTAG_BIOS]
-
-
-
[docs]defis_supported(self)->bool:
- ble_exists=self.cs.is_control_defined('BiosLockEnable')
- bioswe_exists=self.cs.is_control_defined('BiosWriteEnable')
- smmbwp_exists=self.cs.is_control_defined('SmmBiosWriteProtection')
-
- ifble_existsandbioswe_existsandsmmbwp_exists:
- returnTrue
- self.logger.log_important('Required Controls are not defined for platform. Skipping module.')
- self.rc_res.setStatusBit(self.rc_res.status.NOT_APPLICABLE)
- self.res=self.rc_res.getReturnCode(ModuleResult.NOTAPPLICABLE)
- returnFalse
-
-
[docs]defcheck_BIOS_write_protection(self)->int:
- ble=self.cs.get_control('BiosLockEnable',with_print=True)
- bioswe=self.cs.get_control('BiosWriteEnable')
- smmbwp=self.cs.get_control('SmmBiosWriteProtection')
-
- # Is the BIOS flash region write protected?
- write_protected=0
- if(1==ble)and(0==bioswe):
- if1==smmbwp:
- self.logger.log_good("BIOS region write protection is enabled (writes restricted to SMM)")
- write_protected=1
- else:
- self.logger.log_important("Enhanced SMM BIOS region write protection has not been enabled (SMM_BWP is not used)")
- else:
- self.logger.log_bad("BIOS region write protection is disabled!")
-
- returnwrite_protected==1
Source code for chipsec.modules.common.cpu.cpu_info
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2018 - 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
-#
-
-"""
-Displays CPU information
-
-Reference:
- - Intel 64 and IA-32 Architectures Software Developer Manual (SDM)
- - https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html
-
-Usage:
- ``chipsec_main -m common.cpu.cpu_info``
-
-Examples:
- >>> chipsec_main.py -m common.cpu.cpu_info
-
-Registers used:
- - IA32_BIOS_SIGN_ID.Microcode
-
-.. note:
- No PASS/FAIL returned, INFORMATION only.
-
-"""
-
-importstruct
-fromchipsec.module_commonimportBaseModule,ModuleResult
-fromchipsec.definesimportbytestostring
-fromtypingimportList
-
-
Source code for chipsec.modules.common.cpu.ia_untrusted
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2018-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
-#
-
-"""
-IA Untrusted checks
-
-Usage:
- ``chipsec_main -m common.cpu.ia_untrusted``
-
-Examples:
- >>> chipsec_main.py -m common.cpu.ia_untrusted
-
-Registers used:
- - MSR_BIOS_DONE.IA_UNTRUSTED
- - MSR_BIOS_DONE.SoC_BIOS_DONE
-
-"""
-
-fromchipsec.module_commonimportBaseModule,ModuleResult,MTAG_HWCONFIG
-fromtypingimportList
-
-TAGS=[MTAG_HWCONFIG]
-
-
-
[docs]defis_supported(self)->bool:
- ifself.cs.register_has_field('MSR_BIOS_DONE','IA_UNTRUSTED'):
- returnTrue
- self.logger.log_important('MSR_BIOS_DONE.IA_UNTRUSTED is not defined for platform. Skipping checks.')
- self.rc_res.setStatusBit(self.rc_res.status.NOT_APPLICABLE)
- self.res=self.rc_res.getReturnCode(ModuleResult.NOTAPPLICABLE)
- returnFalse
-
-
[docs]defcheck_untrusted(self)->int:
- self.logger.log('[*] Check that untrusted mode has been set.')
- res=ModuleResult.PASSED
- ifself.cs.register_has_field('MSR_BIOS_DONE','SoC_BIOS_DONE'):
- soc=self.cs.read_register_field('MSR_BIOS_DONE','SoC_BIOS_DONE')
- ifsoc==0:
- res=ModuleResult.FAILED
- self.rc_res.setStatusBit(self.rc_res.status.CONFIGURATION)
- self.logger.log_bad('SoC_BIOS_DONE not set.')
- else:
- self.logger.log_good('SoC_BIOS_DONE set.')
-
- self.logger.log("")
- fortidinrange(self.cs.msr.get_cpu_thread_count()):
- bd=self.cs.read_register('MSR_BIOS_DONE',tid)
- ifself.logger.VERBOSE:
- self.cs.print_register('MSR_BIOS_DONE',bd)
- ia_untrusted=self.cs.get_register_field('MSR_BIOS_DONE',bd,"IA_UNTRUSTED")
- ifia_untrusted==0:
- res=ModuleResult.FAILED
- self.rc_res.setStatusBit(self.rc_res.status.CONFIGURATION)
- self.logger.log_bad(f'IA_UNTRUSTED not set on thread {tid:d}.')
- else:
- self.logger.log_good(f'IA_UNTRUSTED set on thread {tid:d}.')
- returnres
-
-
[docs]defrun(self,module_argv:List[str])->int:
- self.logger.start_test('IA_UNTRUSTED Check')
- self.res=self.check_untrusted()
- self.logger.log("")
- ifself.res==ModuleResult.PASSED:
- self.logger.log_passed("IA_UNTRUSTED set on all threads")
- elifself.res==ModuleResult.FAILED:
- self.logger.log_failed("IA_UNTRUSTED not set on all threads")
-
- returnself.rc_res.getReturnCode(self.res)
Source code for chipsec.modules.common.cpu.spectre_v2
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2018, Eclypsium, Inc.
-# Copyright (c) 2019-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.
-#
-
-"""
-The module checks if system includes hardware mitigations for Speculative Execution Side Channel.
-Specifically, it verifies that the system supports CPU mitigations for
-Branch Target Injection vulnerability a.k.a. Spectre Variant 2 (CVE-2017-5715)
-
-The module checks if the following hardware mitigations are supported by the CPU
-and enabled by the OS/software:
-
-1. Indirect Branch Restricted Speculation (IBRS) and Indirect Branch Predictor Barrier (IBPB):
- CPUID.(EAX=7H,ECX=0):EDX[26] == 1
-
-2. Single Thread Indirect Branch Predictors (STIBP):
- CPUID.(EAX=7H,ECX=0):EDX[27] == 1
- IA32_SPEC_CTRL[STIBP] == 1
-
-3. Enhanced IBRS:
- CPUID.(EAX=7H,ECX=0):EDX[29] == 1
- IA32_ARCH_CAPABILITIES[IBRS_ALL] == 1
- IA32_SPEC_CTRL[IBRS] == 1
-
-4. @TODO: Mitigation for Rogue Data Cache Load (RDCL):
- CPUID.(EAX=7H,ECX=0):EDX[29] == 1
- IA32_ARCH_CAPABILITIES[RDCL_NO] == 1
-
-In addition to checking if CPU supports and OS enables all mitigations, we need to check
-that relevant MSR bits are set consistently on all logical processors (CPU threads).
-
-
-The module returns the following results:
-
-FAILED:
- IBRS/IBPB is not supported
-
-WARNING:
- IBRS/IBPB is supported
-
- Enhanced IBRS is not supported
-
-WARNING:
- IBRS/IBPB is supported
-
- Enhanced IBRS is supported
-
- Enhanced IBRS is not enabled by the OS
-
-WARNING:
- IBRS/IBPB is supported
-
- STIBP is not supported or not enabled by the OS
-
-PASSED:
- IBRS/IBPB is supported
-
- Enhanced IBRS is supported
-
- Enhanced IBRS is enabled by the OS
-
- STIBP is supported
-
-
-Notes:
-
-- The module returns WARNING when CPU doesn't support enhanced IBRS
- Even though OS/software may use basic IBRS by setting IA32_SPEC_CTRL[IBRS] when necessary,
- we have no way to verify this
-
-- The module returns WARNING when CPU supports enhanced IBRS but OS doesn't set IA32_SPEC_CTRL[IBRS]
- Under enhanced IBRS, OS can set IA32_SPEC_CTRL[IBRS] once to take advantage of IBRS protection
-
-- The module returns WARNING when CPU doesn't support STIBP or OS doesn't enable it
- Per Speculative Execution Side Channel Mitigations:
- "enabling IBRS prevents software operating on one logical processor from controlling
- the predicted targets of indirect branches executed on another logical processor.
- For that reason, it is not necessary to enable STIBP when IBRS is enabled"
-
-- OS/software may implement "retpoline" mitigation for Spectre variant 2
- instead of using CPU hardware IBRS/IBPB
-
-@TODO: we should verify CPUID.07H:EDX on all logical CPUs as well
-because it may differ if ucode update wasn't loaded on all CPU cores
-
-
-Hardware registers used:
-
-- CPUID.(EAX=7H,ECX=0):EDX[26] - enumerates support for IBRS and IBPB
-- CPUID.(EAX=7H,ECX=0):EDX[27] - enumerates support for STIBP
-- CPUID.(EAX=7H,ECX=0):EDX[29] - enumerates support for the IA32_ARCH_CAPABILITIES MSR
-- IA32_ARCH_CAPABILITIES[IBRS_ALL] - enumerates support for enhanced IBRS
-- IA32_ARCH_CAPABILITIES[RCDL_NO] - enumerates support RCDL mitigation
-- IA32_SPEC_CTRL[IBRS] - enable control for enhanced IBRS by the software/OS
-- IA32_SPEC_CTRL[STIBP] - enable control for STIBP by the software/OS
-
-
-References:
-
-- Reading privileged memory with a side-channel by Jann Horn, Google Project Zero:
- https://googleprojectzero.blogspot.com/2018/01/reading-privileged-memory-with-side.html
-
-- Spectre:
- https://spectreattack.com/spectre.pdf
-
-- Meltdown:
- https://meltdownattack.com/meltdown.pdf
-
-- Speculative Execution Side Channel Mitigations:
- https://software.intel.com/sites/default/files/managed/c5/63/336996-Speculative-Execution-Side-Channel-Mitigations.pdf
-
-- Retpoline: a software construct for preventing branch-target-injection:
- https://support.google.com/faqs/answer/7625886
-
-"""
-
-fromchipsec.module_commonimportBaseModule,MTAG_CPU,MTAG_HWCONFIG,MTAG_SMM,ModuleResult
-fromchipsec.exceptionsimportHWAccessViolationError,UnimplementedAPIError
-fromchipsec.definesimportBIT26,BIT27,BIT29
-fromtypingimportList
-
-TAGS=[MTAG_CPU,MTAG_HWCONFIG,MTAG_SMM]
-
-
-
Source code for chipsec.modules.common.debugenabled
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2018, Eclypsium, Inc.
-# Copyright (c) 2018-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.
-#
-
-"""
-This module checks if the system has debug features turned on,
-specifically the Direct Connect Interface (DCI).
-
-This module checks the following bits:
-1. HDCIEN bit in the DCI Control Register
-2. Debug enable bit in the IA32_DEBUG_INTERFACE MSR
-3. Debug lock bit in the IA32_DEBUG_INTERFACE MSR
-4. Debug occurred bit in the IA32_DEBUG_INTERFACE MSR
-
-Usage:
- ``chipsec_main -m common.debugenabled``
-
-Examples:
- >>> chipsec_main.py -m common.debugenabled
-
-The module returns the following results:
- - **FAILED** : Any one of the debug features is enabled or unlocked.
- - **PASSED** : All debug feature are disabled and locked.
-
-Registers used:
- - IA32_DEBUG_INTERFACE[DEBUGENABLE]
- - IA32_DEBUG_INTERFACE[DEBUGELOCK]
- - IA32_DEBUG_INTERFACE[DEBUGEOCCURED]
- - P2SB_DCI.DCI_CONTROL_REG[HDCIEN]
-
-"""
-
-fromchipsec.module_commonimportBaseModule,ModuleResult
-fromchipsec.definesimportBIT11
-fromtypingimportList
-
-_MODULE_NAME='debugenabled'
-
-
-
[docs]defis_supported(self)->bool:
- # Use CPUID Function 1 to determine if the IA32_DEBUG_INTERFACE MSR is supported.
- # See IA32 SDM CPUID Instruction for details. (SDBG ECX bit 11)
- (_,_,ecx,_)=self.cs.cpu.cpuid(1,0)
- supported=(ecx&BIT11)!=0
- ifnotsupportedandnotself.cs.is_register_defined('ECTRL'):
- self.logger.log_important('CPU Debug features are not supported on this platform. Skipping module.')
- self.rc_res.setStatusBit(self.rc_res.status.NOT_APPLICABLE)
- self.res=self.rc_res.getReturnCode(ModuleResult.NOTAPPLICABLE)
- returnsupported
[docs]defrun(self,module_argv:List[str])->int:
- self.logger.start_test('Debug features test')
-
- cpu_debug_test_fail=self.check_cpu_debug_enable()
-
- dci_test_fail=ModuleResult.PASSED
- ifself.cs.is_register_defined('ECTRL'):
- dci_test_fail=self.check_dci()
-
- self.logger.log('')
- self.logger.log('[*] Module Results:')
-
- ifself.is_debug_set:
- self.logger.log_important('IA32_DEBUG_INTERFACE.DEBUG_OCCURRED bit is set.')
- ifself.is_enable_set:
- self.logger.log_important('IA32_DEBUG_INTERFACE.ENABLE bit is set.')
- ifnotself.is_lock_set:
- self.logger.log_important('IA32_DEBUG_INTERFACE.LOCK bit is NOT set.')
-
- if(dci_test_fail==ModuleResult.FAILED)or(cpu_debug_test_fail==ModuleResult.FAILED):
- self.logger.log_failed('One or more of the debug checks have failed and a debug feature is enabled')
- self.res=self.rc_res.getReturnCode(ModuleResult.FAILED)
- elif(dci_test_fail==ModuleResult.WARNING)or(cpu_debug_test_fail==ModuleResult.WARNING):
- self.logger.log_warning('An unexpected debug state was discovered on this platform')
- self.res=self.rc_res.getReturnCode(ModuleResult.WARNING)
- else:
- self.logger.log_passed('All checks have successfully passed')
-
- returnself.res
-# 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
-#
-
-"""
-Tests that IA-32/IA-64 architectural features are configured and locked, including IA32 Model Specific Registers (MSRs)
-
-Reference:
- - Intel 64 and IA-32 Architectures Software Developer Manual (SDM)
- - https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html
-
-Usage:
- ``chipsec_main -m common.ia32cfg``
-
-Examples:
- >>> chipsec_main.py -m common.ia32cfg
-
-Registers used:
- - IA32_FEATURE_CONTROL
- - Ia32FeatureControlLock (control)
-
-"""
-
-fromchipsec.module_commonimportBaseModule,ModuleResult,MTAG_HWCONFIG
-fromtypingimportList
-
-
-TAGS=[MTAG_HWCONFIG]
-
-
-
[docs]defis_supported(self)->bool:
- ifself.cs.is_register_defined('IA32_FEATURE_CONTROL'):
- ifself.cs.is_control_defined('Ia32FeatureControlLock'):
- returnTrue
- self.logger.log_important('Ia32FeatureControlLock control not defined for platform. Skipping module.')
- else:
- self.logger.log_important('IA32_FEATURE_CONTROL register not defined for platform. Skipping module.')
- self.rc_res.setStatusBit(self.rc_res.status.NOT_APPLICABLE)
- self.res=self.rc_res.getReturnCode(ModuleResult.NOTAPPLICABLE)
- returnFalse
-
-
[docs]defcheck_ia32feature_control(self)->int:
- self.logger.log("[*] Verifying IA32_Feature_Control MSR is locked on all logical CPUs..")
-
- res=ModuleResult.PASSED
- fortidinrange(self.cs.msr.get_cpu_thread_count()):
- ifself.logger.VERBOSE:
- feature_cntl=self.cs.read_register('IA32_FEATURE_CONTROL',tid)
- self.cs.print_register('IA32_FEATURE_CONTROL',feature_cntl)
- feature_cntl_lock=self.cs.get_control('Ia32FeatureControlLock',tid)
- self.logger.log(f"[*] cpu{tid:d}: IA32_FEATURE_CONTROL Lock = {feature_cntl_lock:d}")
- if0==feature_cntl_lock:
- res=ModuleResult.FAILED
- self.rc_res.setStatusBit(self.rc_res.status.LOCKS)
-
-
- ifres==ModuleResult.PASSED:
- self.logger.log_passed("IA32_FEATURE_CONTROL MSR is locked on all logical CPUs")
- else:
- self.logger.log_failed("IA32_FEATURE_CONTROL MSR is not locked on all logical CPUs")
-
- returnself.rc_res.getReturnCode(res)
-
-
[docs]defrun(self,module_argv:List[str])->int:
- self.logger.start_test("IA32 Feature Control Lock")
- self.res=self.check_ia32feature_control()
- returnself.res
Source code for chipsec.modules.common.me_mfg_mode
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2018, Eclypsium, Inc.
-# Copyright (c) 2019-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.
-
-"""
-This module checks that ME Manufacturing mode is not enabled.
-
-References:
-
-https://blog.ptsecurity.com/2018/10/intel-me-manufacturing-mode-macbook.html
-
-`PCI_DEVS.H <https://github.com/coreboot/coreboot/blob/master/src/soc/intel/*/include/soc/pci_devs.h>`_
-
-.. code-block::
-
- #define PCH_DEV_SLOT_CSE 0x16
- #define PCH_DEVFN_CSE _PCH_DEVFN(CSE, 0)
- #define PCH_DEV_CSE _PCH_DEV(CSE, 0)
-
-https://github.com/coreboot/coreboot/blob/master/src/soc/intel/apollolake/cse.c
-
-.. code-block::
-
- fwsts1 = dump_status(1, PCI_ME_HFSTS1);
- # Minimal decoding is done here in order to call out most important
- # pieces. Manufacturing mode needs to be locked down prior to shipping
- # the product so it's called out explicitly.
- printk(BIOS_DEBUG, "ME: Manufacturing Mode : %s", (fwsts1 & (1 << 0x4)) ? "YES" : "NO");
-
-`PCH.H <https://github.com/coreboot/coreboot/blob/master/src/southbridge/intel/*/pch.h>`_
-
-.. code-block::
-
- #define PCH_ME_DEV PCI_DEV(0, 0x16, 0)
-
-`ME.H <https://github.com/coreboot/coreboot/blob/master/src/southbridge/intel/*/me.h>`_
-
-.. code-block::
-
- struct me_hfs {
- u32 working_state: 4;
- u32 mfg_mode: 1;
- u32 fpt_bad: 1;
- u32 operation_state: 3;
- u32 fw_init_complete: 1;
- u32 ft_bup_ld_flr: 1;
- u32 update_in_progress: 1;
- u32 error_code: 4;
- u32 operation_mode: 4;
- u32 reserved: 4;
- u32 boot_options_present: 1;
- u32 ack_data: 3;
- u32 bios_msg_ack: 4;
- } __packed;
-
-`ME_STATUS.C <https://github.com/coreboot/coreboot/blob/master/src/southbridge/intel/*/me_status.c>`_
-
-.. code-block::
-
- printk(BIOS_DEBUG, "ME: Manufacturing Mode : %s", hfs->mfg_mode ? "YES" : "NO");
-
-This module checks the following:
-
- ``HFS.MFG_MODE BDF: 0:22:0 offset 0x40 - Bit [4]``
-
-Usage:
- ``chipsec_main -m common.me_mfg_mode``
-
-Examples:
- >>> chipsec_main.py -m common.me_mfg_mode
-
-The module returns the following results:
-
- FAILED : HFS.MFG_MODE is set
-
- PASSED : HFS.MFG_MODE is not set.
-
-Hardware registers used:
- - HFS.MFG_MODE
-"""
-
-fromchipsec.module_commonimportBaseModule,ModuleResult
-fromtypingimportList
-
-
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-2020, 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
-#
-
-
-"""
-This module verifies memory map secure configuration,
-that memory map registers are correctly configured and locked down.
-
-Usage:
- ``chipsec_main -m common.memconfig``
-
-Example:
- >>> chipsec_main.py -m common.memconfig
-
-.. note::
- - This module will only run on Core (client) platforms.
-"""
-
-fromchipsec.module_commonimportBaseModule,ModuleResult,MTAG_HWCONFIG
-fromtypingimportList
-
-_MODULE_NAME='memconfig'
-
-TAGS=[MTAG_HWCONFIG]
-
-
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2018, Eclypsium, Inc.
-# Copyright (c) 2019-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.
-#
-
-"""
-This module checks if memory configuration is locked to protect SMM
-
-Reference:
- - https://github.com/coreboot/coreboot/blob/master/src/cpu/intel/model_206ax/finalize.c
- - https://github.com/coreboot/coreboot/blob/master/src/soc/intel/broadwell/include/soc/msr.h
-
-This module checks the following:
-- MSR_LT_LOCK_MEMORY MSR (0x2E7) - Bit [0]
-
-The module returns the following results:
- - **FAILED** : MSR_LT_LOCK_MEMORY[0] is not set
- - **PASSED** : MSR_LT_LOCK_MEMORY[0] is set
- - **ERROR** : Problem reading MSR_LT_LOCK_MEMORY values
-
-Usage:
- ``chipsec_main -m common.memlock``
-
-Example:
- >>> chipsec_main.py -m common.memlock
-
-Registers used:
- - MSR_LT_LOCK_MEMORY
-
-.. note::
- - This module will not run on Atom based platforms.
-
-"""
-
-fromchipsec.module_commonimportBaseModule,ModuleResult
-fromchipsec.exceptionsimportHWAccessViolationError
-fromtypingimportList
-
-_MODULE_NAME='memlock'
-
-
-
[docs]defis_supported(self)->bool:
- # Workaround for Atom based processors. Accessing this MSR on these systems
- # causes a GP fault and can't be caught in UEFI Shell.
- ifnotself.cs.is_atom():
- ifself.cs.register_has_field('MSR_LT_LOCK_MEMORY','LT_LOCK'):
- returnTrue
- else:
- self.logger.log_important("'MSR_LT_LOCK_MEMORY.LT_LOCK' not defined for platform. Skipping module.")
- else:
- self.logger.log_important('Found an Atom based platform. Skipping module.')
- self.rc_res.setStatusBit(self.rc_res.status.NOT_APPLICABLE)
- self.res=self.rc_res.getReturnCode(ModuleResult.NOTAPPLICABLE)
- returnFalse
[docs]defrun(self,module_argv:List[str])->int:
- self.logger.start_test("Check MSR_LT_LOCK_MEMORY")
- check_MSR_LT_LOCK_MEMORY_test_fail=self.check_MSR_LT_LOCK_MEMORY()
-
- ifself.is_read_error:
- self.logger.log_error('There was a problem reading MSR_LT_LOCK_MEMORY.')
- self.logger.log_important('Possible the environment or a platform feature is preventing these reads.')
- self.res=ModuleResult.ERROR
- self.rc_res.setStatusBit(self.rc_res.status.ACCESS_RW)
- elifcheck_MSR_LT_LOCK_MEMORY_test_fail==True:
- self.logger.log_failed("MSR_LT_LOCK_MEMORY.LT_LOCK bit is not configured correctly")
- self.res=ModuleResult.FAILED
- self.rc_res.setStatusBit(self.rc_res.status.LOCKS)
- else:
- self.logger.log_passed('MSR_LT_LOCK_MEMORY.LT_LOCK bit is set')
- self.res=ModuleResult.PASSED
-
- returnself.rc_res.getReturnCode(self.res)
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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
-#
-
-
-"""
-Check Memory Remapping Configuration
-
-Reference:
- - `Preventing & Detecting Xen Hypervisor Subversions <http://www.invisiblethingslab.com/resources/bh08/part2-full.pdf>`_ by Joanna Rutkowska & Rafal Wojtczuk
-
-Usage:
- ``chipsec_main -m common.remap``
-
-Example:
- >>> chipsec_main.py -m common.remap
-
-Registers used:
- - PCI0.0.0_REMAPBASE
- - PCI0.0.0_REMAPLIMIT
- - PCI0.0.0_TOUUD
- - PCI0.0.0_TOLUD
- - PCI0.0.0_TSEGMB
-
-.. note::
- - This module will only run on Core platforms.
-
-"""
-
-fromchipsec.module_commonimportBaseModule,ModuleResult,MTAG_HWCONFIG,MTAG_SMM
-fromchipsec.definesimportBIT32,ALIGNED_1MB
-
-_MODULE_NAME='remap'
-
-TAGS=[MTAG_SMM,MTAG_HWCONFIG]
-
-
-_REMAP_ADDR_MASK=0x7FFFF00000
-_TOLUD_MASK=0xFFFFF000
-
-
-
[docs]defis_ibecc_enabled(self)->bool:
- ifself.cs.is_register_defined('IBECC_ACTIVATE'):
- edsr=self.cs.read_register_field('IBECC_ACTIVATE','IBECC_EN')
- ifedsr==1:
- returnTrue
- else:
- self.logger.log_verbose('IBECC is not enabled!')
- else:
- self.logger.log_verbose('IBECC is not defined!')
- returnFalse
-
-
[docs]defcheck_remap_config(self)->int:
- is_warning=False
-
- 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(f"[*] TOUUD : 0x{touud:016X}")
- self.logger.log(f"[*] REMAPLIMIT: 0x{remaplimit:016X}")
- self.logger.log(f"[*] REMAPBASE : 0x{remapbase:016X}")
- self.logger.log(f"[*] TOLUD : 0x{tolud:08X}")
- self.logger.log(f"[*] TSEGMB : 0x{tsegmb:08X}")
- self.logger.log("")
-
- ia_untrusted=0
- ifself.cs.register_has_field('MSR_BIOS_DONE','IA_UNTRUSTED'):
- ia_untrusted=self.cs.read_register_field('MSR_BIOS_DONE','IA_UNTRUSTED')
- remapbase_lock=remapbase&0x1
- remaplimit_lock=remaplimit&0x1
- touud_lock=touud&0x1
- tolud_lock=tolud&0x1
- remapbase&=_REMAP_ADDR_MASK
- remaplimit&=_REMAP_ADDR_MASK
- touud&=_REMAP_ADDR_MASK
- tolud&=_TOLUD_MASK
- tsegmb&=_TOLUD_MASK
- self.logger.log("[*] Memory Map:")
- self.logger.log(f"[*] Top Of Upper Memory: 0x{touud:016X}")
- self.logger.log(f"[*] Remap Limit Address: 0x{(remaplimit|0xFFFFF):016X}")
- self.logger.log(f"[*] Remap Base Address : 0x{remapbase:016X}")
- self.logger.log(f"[*] 4GB : 0x{BIT32:016X}")
- self.logger.log(f"[*] Top Of Low Memory : 0x{tolud:016X}")
- self.logger.log(f"[*] TSEG (SMRAM) Base : 0x{tsegmb:016X}")
- self.logger.log('')
-
- remap_ok=True
-
- self.logger.log("[*] Checking memory remap configuration..")
-
- ifremapbase==remaplimit:
- self.logger.log("[!] Memory Remap status is Unknown")
- is_warning=True
- elifremapbase>remaplimit:
- self.logger.log("[*] Memory Remap is disabled")
- else:
- self.logger.log("[*] Memory Remap is enabled")
- remaplimit_addr=(remaplimit|0xFFFFF)
- ifself.is_ibecc_enabled():
- ok=(remaplimit_addr>touud)and(remapbase<touud)
- else:
- ok=((remaplimit_addr+1)==touud)
- remap_ok=remap_okandok
- ifok:
- 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&ALIGNED_1MB)and \
- (0==touud&ALIGNED_1MB)and \
- (0==remapbase&ALIGNED_1MB)and \
- (0==remaplimit&ALIGNED_1MB)
- remap_ok=remap_okandok
- ifok:
- 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)or(0!=ia_untrusted)
- remap_ok=remap_okandok
- ifok:
- self.logger.log_good(" TOUUD is locked")
- else:
- self.logger.log_bad(" TOUUD is not locked")
-
- ok=(0!=tolud_lock)or(0!=ia_untrusted)
- remap_ok=remap_okandok
- ifok:
- self.logger.log_good(" TOLUD is locked")
- else:
- self.logger.log_bad(" TOLUD is not locked")
-
- ok=((0!=remapbase_lock)and(0!=remaplimit_lock))or(0!=ia_untrusted)
- remap_ok=remap_okandok
- ifok:
- self.logger.log_good(" REMAPBASE and REMAPLIMIT are locked")
- else:
- self.logger.log_bad(" REMAPBASE and REMAPLIMIT are not locked")
-
- ifremap_ok:
- ifis_warning:
- self.logger.log_warning("Most Memory Remap registers are configured correctly and locked")
- self.logger.log("[!] Manual verification of REMAP BASE and LIMIT register values may be needed.")
- res=ModuleResult.WARNING
- self.rc_res.setStatusBit(self.rc_res.status.VERIFY)
- else:
- res=ModuleResult.PASSED
- self.rc_res.setStatusBit(self.rc_res.status.SUCCESS)
- self.logger.log_passed("Memory Remap is configured correctly and locked")
- else:
- res=ModuleResult.FAILED
- self.rc_res.setStatusBit(self.rc_res.status.CONFIGURATION)
- self.rc_res.setStatusBit(self.rc_res.status.LOCKS)
- self.logger.log_failed("Memory Remap is not properly configured/locked. Remaping attack may be possible")
-
- returnself.rc_res.getReturnCode(res)
-
-
- # --------------------------------------------------------------------------
- # run( module_argv )
- # Required function: run here all tests from this module
- # --------------------------------------------------------------------------
-
Source code for chipsec.modules.common.secureboot.variables
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-2020, 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
-#
-
-
-"""
-Verify that all Secure Boot key UEFI variables are authenticated (BS+RT+AT)
-and protected from unauthorized modification.
-
-Reference:
- - `UEFI 2.4 spec Section 28 <http://uefi.org/>`_
-
-Usage:
- ``chipsec_main -m common.secureboot.variables [-a modify]``
- - ``-a`` : modify = will try to write/corrupt the variables
-
-Where:
- - ``[]``: optional line
-
-Examples:
- >>> chipsec_main.py -m common.secureboot.variables
- >>> chipsec_main.py -m common.secureboot.variables -a modify
-
-.. note::
- - Module is not supported in all environments.
-
-"""
-
-
-fromchipsec.module_commonimportBaseModule,ModuleResult,MTAG_SECUREBOOT,OPT_MODIFY
-fromchipsec.hal.uefiimportUEFI,SECURE_BOOT_VARIABLES,IS_VARIABLE_ATTRIBUTE,EFI_VAR_NAME_SecureBoot,SECURE_BOOT_KEY_VARIABLES
-fromchipsec.hal.uefiimportEFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS,EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
-fromchipsec.hal.uefiimportSECURE_BOOT_OPTIONAL_VARIABLES
-fromchipsec.hal.uefi_commonimportStatusCode
-fromtypingimportAnyStr,List,Optional
-
-# ############################################################
-# SPECIFY PLATFORMS THIS MODULE IS APPLICABLE TO
-# ############################################################
-_MODULE_NAME='variables'
-
-
-TAGS=[MTAG_SECUREBOOT]
-
-
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-2022, 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
-#
-# Authors:
-# Sushmith Hiremath, INTEL DCG RED team
-#
-
-"""
-Check SGX related configuration
-
-Reference:
- - SGX BWG, CDI/IBP#: 565432
-
-Usage:
- ``chipsec_main -m common.sgx_check``
-
-Examples:
- >>> chipsec_main.py -m common.sgx_check
-
-Registers used:
- - IA32_FEATURE_CONTROL.SGX_GLOBAL_EN
- - IA32_FEATURE_CONTROL.LOCK
- - IA32_DEBUG_INTERFACE.ENABLE
- - IA32_DEBUG_INTERFACE.LOCK
- - MTRRCAP.PRMRR
- - PRMRR_VALID_CONFIG
- - PRMRR_PHYBASE.PRMRR_base_address_fields
- - PRMRR_PHYBASE.PRMRR_MEMTYPE
- - PRMRR_MASK.PRMRR_mask_bits
- - PRMRR_MASK.PRMRR_VLD
- - PRMRR_MASK.PRMRR_LOCK
- - PRMRR_UNCORE_PHYBASE.PRMRR_base_address_fields
- - PRMRR_UNCORE_MASK.PRMRR_mask_bits
- - PRMRR_UNCORE_MASK.PRMRR_VLD
- - PRMRR_UNCORE_MASK.PRMRR_LOCK
- - BIOS_SE_SVN.PFAT_SE_SVN
- - BIOS_SE_SVN.ANC_SE_SVN
- - BIOS_SE_SVN.SCLEAN_SE_SVN
- - BIOS_SE_SVN.SINIT_SE_SVN
- - BIOS_SE_SVN_STATUS.LOCK
- - SGX_DEBUG_MODE.SGX_DEBUG_MODE_STATUS_BIT
-
-.. note::
- - Will not run within the EFI Shell
-
-"""
-
-_MODULE_NAME='sgx_check'
-fromchipsec.exceptionsimportHWAccessViolationError
-fromchipsec.module_commonimportBaseModule,ModuleResult,MTAG_HWCONFIG
-fromchipsec.definesimportBIT0,BIT1,BIT2,BIT5,BIT6,BIT7,BIT8
-TAGS=[MTAG_HWCONFIG]
-
-
-
[docs]defis_supported(self)->bool:
- sgx_cpu_support=False
- ifself.cs.os_helper.is_efi():
- self.logger.log_important('Currently this module cannot run within the EFI Shell. Exiting.')
- elifnotself.cs.register_has_field('IA32_FEATURE_CONTROL','SGX_GLOBAL_EN'):
- self.logger.log_important('IA32_FEATURE_CONTROL.SGX_GLOBAL_EN not defined for platform. Skipping module.')
- else:
- fortidinrange(self.cs.msr.get_cpu_thread_count()):
- status=self.helper.set_affinity(tid)
- ifstatus==-1:
- self.logger.log_verbose(f"[*] Failed to set affinity to CPU{tid:d}")
- (_,r_ebx,_,_)=self.cs.cpu.cpuid(0x07,0x00)
- ifr_ebx&BIT2:
- self.logger.log_verbose(f"[*] CPU{tid:d}: does support SGX")
- sgx_cpu_support=True
- else:
- self.logger.log_verbose(f"[*]CPU{tid:d}: does not support SGX")
- self.logger.log_important('SGX not supported. Skipping module.')
- ifnotsgx_cpu_support:
- self.rc_res.setStatusBit(self.rc_res.status.NOT_APPLICABLE)
- self.res=self.rc_res.getReturnCode(ModuleResult.NOTAPPLICABLE)
- returnsgx_cpu_support
-
-
[docs]defcheck_sgx_config(self)->int:
- self.logger.log("[*] Test if CPU has support for SGX")
- sgx_ok=False
-
- self.logger.log("\n[*] SGX BIOS enablement check")
- self.logger.log("[*] Verifying IA32_FEATURE_CONTROL MSR is configured")
- bios_feature_control_enable=True
- fortidinrange(self.cs.msr.get_cpu_thread_count()):
- ifnot(self.cs.read_register_field('IA32_FEATURE_CONTROL','SGX_GLOBAL_EN',False,tid)==1):
- bios_feature_control_enable=False
- ifbios_feature_control_enable:
- self.logger.log_good("Intel SGX is Enabled in BIOS")
- else:
- self.logger.log_important("Intel SGX is not enabled in BIOS")
- self.res=ModuleResult.WARNING
- self.rc_res.setStatusBit(self.rc_res.status.FEATURE_DISABLED)
-
- self.logger.log("\n[*] Verifying IA32_FEATURE_CONTROL MSR is locked")
- locked=True
- fortidinrange(self.cs.msr.get_cpu_thread_count()):
- feature_cntl_lock=self.cs.get_control('Ia32FeatureControlLock',tid)
- self.logger.log_verbose(f"[*] cpu{tid:d}: IA32_Feature_Control Lock = {feature_cntl_lock:d}")
- if0==feature_cntl_lock:
- locked=False
- iflocked:
- self.logger.log_good("IA32_Feature_Control locked")
- else:
- self.logger.log_bad("IA32_Feature_Control is unlocked")
- self.res=ModuleResult.FAILED
- self.rc_res.setStatusBit(self.rc_res.status.LOCKS)
-
- # Verify that Protected Memory Range (PRM) is supported, MSR IA32_MTRRCAP (FEh) [12]=1
- # Check on every CPU and make sure that they are all the same values
- self.logger.log("\n[*] Verifying if Protected Memory Range (PRMRR) is configured")
- prmrr_enable=False
- fortidinrange(self.cs.msr.get_cpu_thread_count()):
- mtrrcap=self.cs.read_register_field('MTRRCAP','PRMRR',False,tid)
- ifmtrrcap==0:
- self.logger.log_verbose(f"[*] CPU{tid:d} Protected Memory Range configuration is not supported")
- else:
- prmrr_enable=True
- self.logger.log_verbose(f"[*] CPU{tid:d} Protected Memory Range configuration is supported")
- ifprmrr_enable:
- self.logger.log_good("Protected Memory Range configuration is supported")
- else:
- self.logger.log_bad("Protected Memory Range configuration is not supported")
- self.res-ModuleResult.FAILED
- self.rc_res.setStatusBit(self.rc_res.status.UNSUPPORTED_FEATURE)
-
- # Check PRMRR configurations on each core.
- self.logger.log("\n[*] Verifying PRMRR Configuration on each core.")
-
- self.prmrr=self.PRMRR(self.logger,self.cs)
- try:
- self.prmrr._check_prmrr()
- exceptHWAccessViolationError:
- self.prmrr.reset_variables()
- self.logger.log_important("Some PRMRR registers could not be read. Following results may not be accurate.")
- ifself.cs.os_helper.is_windows():
- self.logger.log_important("Please try running in a Linux environment. The results there may be more complete.")
- else:
- self.check_prmrr_values()
-
-
-
- ifbios_feature_control_enableandlocked:
- sgx1_instr_support=False
- sgx2_instr_support=False
- self.logger.log("\n[*] Verifying if SGX instructions are supported")
- fortidinrange(self.cs.msr.get_cpu_thread_count()):
- status=self.helper.set_affinity(tid)
- ifstatus==-1:
- self.logger.log_verbose(f"[*] Failed to set affinity to CPU{tid:d}")
- (r_eax,_,_,_)=self.cs.cpu.cpuid(0x012,0x00)
- ifr_eax&BIT0:
- self.logger.log_verbose(f"[*] CPU{tid:d} SGX-1 instructions are supported")
- sgx1_instr_support=True
- else:
- self.logger.log_verbose(f"[*] CPU{tid:d} SGX-1 instructions are not supported")
- ifr_eax&BIT1:
- self.logger.log_verbose(f"[*] CPU{tid:d} SGX-2 instructions are supported")
- sgx2_instr_support=True
- else:
- self.logger.log_verbose(f"[*] CPU{tid:d} SGX-2 instructions are not supported")
- ifsgx1_instr_support:
- self.logger.log_good("Intel SGX instructions are supported and available to use")
- sgx_ok=True
- else:
- self.logger.log_bad("Intel SGX instructions are not supported on system")
- sgx_ok=False
- ifsgx2_instr_support:
- self.logger.log("[*] SGX-2 instructions are supported")
- else:
- self.logger.log("[*] SGX-2 instructions are not supported")
- else:
- sgx_ok=False
-
- self.logger.log("\n[*] Verifying if SGX is available to use")
- ifsgx_okandprmrr_enableandself.prmrr.uniform:
- self.logger.log_good("Intel SGX is available to use")
- elif(notsgx_ok)and(notbios_feature_control_enable)andprmrr_enableandself.prmrr.uniform:
- self.logger.log_important("Intel SGX instructions disabled by firmware")
- self.rc_res.setStatusBit(self.rc_res.status.FEATURE_DISABLED)
- ifself.res==ModuleResult.PASSED:
- self.res=ModuleResult.WARNING
- else:
- self.logger.log_bad("Intel SGX is not available to use")
- self.res=ModuleResult.FAILED
- self.rc_res.setStatusBit(self.rc_res.status.FEATURE_DISABLED)
-
- ifself.cs.is_register_defined('BIOS_SE_SVN')andself.cs.is_register_defined('BIOS_SE_SVN_STATUS'):
- self.cs.print_register('BIOS_SE_SVN',self.cs.read_register('BIOS_SE_SVN'))
- self.cs.print_register('BIOS_SE_SVN_STATUS',self.cs.read_register('BIOS_SE_SVN_STATUS'))
-
- self.logger.log("\n[*] Check SGX debug feature settings")
- sgx_debug_status=self.cs.read_register_field('SGX_DEBUG_MODE','SGX_DEBUG_MODE_STATUS_BIT')
- self.logger.log(f"[*] SGX Debug Enable : {sgx_debug_status:d}")
- self.logger.log("[*] Check Silicon debug feature settings")
- debug_interface=self.cs.read_register('IA32_DEBUG_INTERFACE')
- self.logger.log(f"[*] IA32_DEBUG_INTERFACE : 0x{debug_interface:08X}")
- debug_enable=self.cs.get_register_field('IA32_DEBUG_INTERFACE',debug_interface,'ENABLE')
- debug_lock=self.cs.get_register_field('IA32_DEBUG_INTERFACE',debug_interface,'LOCK')
- self.logger.log(f"[*] Debug enabled : {debug_enable:d}")
- self.logger.log(f"[*] Lock : {debug_lock:d}")
-
- ifsgx_debug_status==1:
- self.logger.log_bad("SGX debug mode is enabled")
- self.res=ModuleResult.FAILED
- self.rc_res.setStatusBit(self.rc_res.status.DEBUG_FEATURE)
- else:
- self.logger.log_good("SGX debug mode is disabled")
- ifdebug_enable==0:
- self.logger.log_good("Silicon debug features are disabled")
- else:
- self.logger.log_bad("Silicon debug features are not disabled")
- self.res=ModuleResult.FAILED
- self.rc_res.setStatusBit(self.rc_res.status.DEBUG_FEATURE)
- if(0==debug_enable)and(1==sgx_debug_status):
- self.logger.log_bad("Enabling sgx_debug without enabling debug mode in msr IA32_DEBUG_INTERFACE is not a valid configuration")
- self.res=ModuleResult.FAILED
- self.rc_res.setStatusBit(self.rc_res.status.CONFIGURATION)
- ifdebug_lock==1:
- self.logger.log_good("Silicon debug Feature Control register is locked")
- else:
- self.logger.log_bad("Silicon debug Feature Control register is not locked")
- self.res=ModuleResult.FAILED
- self.rc_res.setStatusBit(self.rc_res.status.LOCKS)
-
- returnself.res
-
-
-
[docs]defcheck_prmrr_values(self)->None:
- ifnotself.prmrr:
- return
- ifnotself.prmrr.uniform:
- self.logger.log_bad("PRMRR config is not uniform across all CPUs")
- self.res=ModuleResult.FAILED
- self.rc_res.setStatusBit(self.rc_res.status.CONFIGURATION)
- else:
- self.logger.log_good("PRMRR config is uniform across all CPUs")
- prmrr_configs=[]
- config_support=False
- ifBIT0&self.prmrr.valid_config:
- prmrr_configs.append("1M")
- config_support=True
- ifBIT1&self.prmrr.valid_config:
- prmrr_configs.append("2M")
- config_support=True
- ifBIT5&self.prmrr.valid_config:
- prmrr_configs.append("32M")
- config_support=True
- ifBIT6&self.prmrr.valid_config:
- prmrr_configs.append("64M")
- config_support=True
- ifBIT7&self.prmrr.valid_config:
- prmrr_configs.append("128M")
- config_support=True
- ifBIT8&self.prmrr.valid_config:
- prmrr_configs.append("256M")
- config_support=True
- ifconfig_support:
- self.logger.log(f"[*] PRMRR config supports: {', '.join(prmrr_configs)}")
- else:
- self.logger.log("[*] PRMMR config has improper value")
-
- # In some cases the PRMRR base and mask may be zero
- if(self.prmrr.base==0)and(self.prmrr.mask==0):
- self.logger.log("[*] PRMRR Base and Mask are set to zero. PRMRR appears to be disabled.")
- self.logger.log("[*] Skipping Base/Mask settings.")
- else:
- self.logger.log(f"[*] PRMRR base address: 0x{self.prmrr.base:012X}")
- self.logger.log("[*] Verifying PRMR memory type is valid")
- self.logger.log(f"[*] PRMRR memory type : 0x{self.prmrr.base_memtype:X}")
- ifself.prmrr.base_memtype==0x6:
- self.logger.log_good("PRMRR memory type is WB as expected")
- else:
- self.logger.log_bad("Unexpected PRMRR memory type (not WB)")
- self.res=ModuleResult.FAILED
- self.rc_res.setStatusBit(self.rc_res.status.CONFIGURATION)
- self.logger.log(f"[*] PRMRR mask address: 0x{self.prmrr.mask:012X}")
- self.logger.log("[*] Verifying PRMR address are valid")
- self.logger.log(f"[*] PRMRR uncore mask valid: 0x{self.prmrr.uncore_mask_vld:d}")
- ifself.prmrr.mask_vld==0x1:
- self.logger.log_good("Mcheck marked PRMRR address as valid")
- else:
- self.logger.log_bad("Mcheck marked PRMRR address as invalid")
- self.res=ModuleResult.FAILED
- self.rc_res.setStatusBit(self.rc_res.status.CONFIGURATION)
- self.logger.log("[*] Verifying if PRMR mask register is locked")
- self.logger.log(f"[*] PRMRR mask lock: 0x{self.prmrr.mask_lock:X}")
- ifself.prmrr.locked:
- self.logger.log_good("PRMRR MASK register is locked")
- else:
- self.logger.log_bad("PRMRR MASK register is not locked")
- self.res=ModuleResult.FAILED
- self.rc_res.setStatusBit(self.rc_res.status.LOCKS)
- ifself.prmrr.check_uncore_vals:
- self.logger.log(f"[*] PRMRR uncore base address: 0x{self.prmrr.uncore_base:012X}")
- self.logger.log(f"[*] PRMRR uncore mask address: 0x{self.prmrr.uncore_mask:012X}")
- self.logger.log("[*] Verifying PRMR uncore address are valid")
- self.logger.log(f"[*] PRMRR uncore mask valid: 0x{self.prmrr.uncore_mask_vld:X}")
- ifself.prmrr.uncore_mask_vld==0x1:
- self.logger.log_good("Mcheck marked uncore PRMRR address as valid")
- else:
- self.logger.log_bad("Mcheck marked uncore PRMRR address as invalid")
- self.res=ModuleResult.FAILED
- self.rc_res.setStatusBit(self.rc_res.status.CONFIGURATION)
- self.logger.log("[*] Verifying if PRMR uncore mask register is locked")
- self.logger.log(f"[*] PRMRR uncore mask lock: 0x{self.prmrr.uncore_mask_lock:X}")
- ifself.prmrr.uncore_mask_lock==0x1:
- self.logger.log_good("PMRR uncore MASK register is locked")
- else:
- self.logger.log_bad("PMRR uncore MASK register is not locked")
- self.res=ModuleResult.FAILED
- self.rc_res.setStatusBit(self.rc_res.status.LOCKS)
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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
-#
-
-
-"""
-Compatible SMM memory (SMRAM) Protection check module
-This CHIPSEC module simply reads SMRAMC and checks that D_LCK is set.
-
-Reference:
-In 2006, `Security Issues Related to Pentium System Management Mode <http://www.ssi.gouv.fr/archive/fr/sciences/fichiers/lti/cansecwest2006-duflot.pdf>`_ outlined a configuration issue where compatibility SMRAM was not locked on some platforms. This means that ring 0 software was able to modify System Management Mode (SMM) code and data that should have been protected.
-
-In Compatability SMRAM (CSEG), access to memory is defined by the SMRAMC register. When SMRAMC[D_LCK] is not set by the BIOS, SMRAM can be accessed even when the CPU is not in SMM. Such attacks were also described in `Using CPU SMM to Circumvent OS Security Functions <http://fawlty.cs.usfca.edu/~cruse/cs630f06/duflot.pdf>`_ and `Using SMM for Other Purposes <http://phrack.org/issues/65/7.html>`_.
-
-usage:
- ``chipsec_main -m common.smm``
-
-Examples:
- >>> chipsec_main.py -m common.smm
-
-This module will only run on client (core) platforms that have PCI0.0.0_SMRAMC defined.
-"""
-
-fromchipsec.module_commonimportBaseModule,ModuleResult,MTAG_BIOS,MTAG_SMM
-fromtypingimportList
-
-TAGS=[MTAG_BIOS,MTAG_SMM]
-
-
-
[docs]defis_supported(self)->bool:
- ifself.cs.is_core()andself.cs.is_register_defined('PCI0.0.0_SMRAMC'):
- returnTrue
- self.logger.log("Either not a Core (client) platform or 'PCI0.0.0_SMRAMC' not defined for platform. Skipping module.")
- self.rc_res.setStatusBit(self.rc_res.status.NOT_APPLICABLE)
- self.res=self.rc_res.getReturnCode(ModuleResult.NOTAPPLICABLE)
- returnFalse
-
-
[docs]defcheck_SMRAMC(self)->int:
-
- regval=self.cs.read_register('PCI0.0.0_SMRAMC')
- g_smrame=self.cs.get_register_field('PCI0.0.0_SMRAMC',regval,'G_SMRAME')
- d_open=self.cs.get_register_field('PCI0.0.0_SMRAMC',regval,'D_OPEN')
- d_lock=self.cs.get_register_field('PCI0.0.0_SMRAMC',regval,'D_LCK')
-
- self.cs.print_register('PCI0.0.0_SMRAMC',regval)
-
- if1==g_smrame:
- self.logger.log("[*] Compatible SMRAM is enabled")
- # When D_LCK is set HW clears D_OPEN so generally no need to check for D_OPEN but doesn't hurt double checking
- if(1==d_lock)and(0==d_open):
- res=ModuleResult.PASSED
- self.logger.log_passed("Compatible SMRAM is locked down")
- else:
- res=ModuleResult.FAILED
- self.logger.log_failed("Compatible SMRAM is not properly locked. Expected ( D_LCK = 1, D_OPEN = 0 )")
- self.rc_res.setStatusBit(self.rc_res.status.LOCKS)
- else:
- res=ModuleResult.NOTAPPLICABLE
- self.rc_res.setStatusBit(self.rc_res.status.FEATURE_DISABLED)
- self.logger.log("[*] Compatible SMRAM is not enabled. Skipping..")
-
- returnself.rc_res.getReturnCode(res)
-
- # --------------------------------------------------------------------------
- # run( module_argv )
- # Required function: run here all tests from this module
- # --------------------------------------------------------------------------
-
Source code for chipsec.modules.common.smm_code_chk
-# -*- coding: utf-8 -*-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2021, SentinelOne
-# Copyright (c) 2021, Intel
-#
-# 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.
-
-"""
-SMM_Code_Chk_En (SMM Call-Out) Protection check
-
-SMM_Code_Chk_En is a bit found in the MSR_SMM_FEATURE_CONTROL register.
-Once set to '1', any CPU that attempts to execute SMM code not within the ranges defined by the SMRR will assert an unrecoverable MCE.
-As such, enabling and locking this bit is an important step in mitigating SMM call-out vulnerabilities.
-This CHIPSEC module simply reads the register and checks that SMM_Code_Chk_En is set and locked.
-
-Reference:
- - Intel 64 and IA-32 Architectures Software Developer Manual (SDM)
- - https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html
-
-Usage:
- ``chipsec_main -m common.smm_code_chk``
-
-Examples:
- >>> chipsec_main.py -m common.smm_code_chk
-
-Registers used:
- - MSR_SMM_FEATURE_CONTROL.LOCK
- - MSR_SMM_FEATURE_CONTROL.SMM_Code_Chk_En
-
-.. note::
- - MSR_SMM_FEATURE_CONTROL may not be defined or readable on all platforms.
-
-"""
-fromchipsec.exceptionsimportHWAccessViolationError
-fromchipsec.module_commonimportBaseModule,ModuleResult,MTAG_BIOS,MTAG_SMM
-fromtypingimportList
-
-TAGS=[MTAG_BIOS,MTAG_SMM]
-
-
-
[docs]defis_supported(self)->bool:
- ifnotself.cs.is_register_defined('MSR_SMM_FEATURE_CONTROL'):
- # The MSR_SMM_FEATURE_CONTROL register is available starting from:
- # * 4th Generation Intel® Core™ Processors (Haswell microarchitecture)
- # * Atom Processors Based on the Goldmont Microarchitecture
- self.logger.log_important('Register MSR_SMM_FEATURE_CONTROL not defined for platform. Skipping module.')
- self.rc_res.setStatusBit(self.rc_res.status.NOT_APPLICABLE)
- self.res=self.rc_res.getReturnCode(ModuleResult.NOTAPPLICABLE)
- returnFalse
-
- # The Intel SDM states that MSR_SMM_FEATURE_CONTROL can only be accessed while the CPU executes in SMM.
- # However, in reality many users report that there is no problem reading this register from outside of SMM.
- # Just to be on the safe side of things, we'll verify we can read this register successfully before moving on.
- try:
- self.cs.read_register('MSR_SMM_FEATURE_CONTROL')
- exceptHWAccessViolationError:
- self.logger.log_important('MSR_SMM_FEATURE_CONTROL is unreadable. Skipping module.')
- self.rc_res.setStatusBit(self.rc_res.status.NOT_APPLICABLE)
- self.res=self.rc_res.getReturnCode(ModuleResult.NOTAPPLICABLE)
- returnFalse
- else:
- returnTrue
-
- def_check_SMM_Code_Chk_En(self,thread_id:int)->int:
- regval=self.cs.read_register('MSR_SMM_FEATURE_CONTROL',thread_id)
- lock=self.cs.get_register_field('MSR_SMM_FEATURE_CONTROL',regval,'LOCK')
- code_chk_en=self.cs.get_register_field('MSR_SMM_FEATURE_CONTROL',regval,'SMM_Code_Chk_En')
-
- self.cs.print_register('MSR_SMM_FEATURE_CONTROL',regval,cpu_thread=thread_id)
-
- if1==code_chk_en:
- if1==lock:
- res=ModuleResult.PASSED
- else:
- res=ModuleResult.FAILED
- self.rc_res.setStatusBit(self.rc_res.status.LOCKS)
- else:
- # MSR_SMM_MCA_CAP (the register that reports enhanced SMM capabilities) can only be read from SMM.
- # Thus, there is no way to tell whether the the CPU doesn't support SMM_Code_Chk_En in the first place,
- # or the CPU supports SMM_Code_Chk_En but the BIOS forgot to enable it.
- #
- # In either case, there is nothing that prevents SMM code from executing instructions outside the ranges defined by the SMRRs,
- # so we should at least issue a warning regarding that.
- res=ModuleResult.WARNING
-
- returnres
-
-
[docs]defcheck_SMM_Code_Chk_En(self)->int:
-
- results=[]
- fortidinrange(self.cs.msr.get_cpu_thread_count()):
- results.append(self._check_SMM_Code_Chk_En(tid))
-
- # Check that all CPUs have the same value of MSR_SMM_FEATURE_CONTROL.
- ifnotall(_==results[0]for_inresults):
- self.logger.log_failed("MSR_SMM_FEATURE_CONTROL does not have the same value across all CPUs")
- self.rc_res.setStatusBit(self.rc_res.status.POTENTIALLY_VULNERABLE)
- returnModuleResult.FAILED
-
- res=results[0]
- ifres==ModuleResult.FAILED:
- self.logger.log_failed("SMM_Code_Chk_En is enabled but not locked down")
- self.rc_res.setStatusBit(self.rc_res.status.LOCKS)
- elifres==ModuleResult.WARNING:
- self.logger.log_warning("""[*] SMM_Code_Chk_En is not enabled.
-This can happen either because this feature is not supported by the CPU or because the BIOS forgot to enable it.
-Please consult the Intel SDM to determine whether or not your CPU supports SMM_Code_Chk_En.""")
- self.rc_res.setStatusBit(self.rc_res.status.VERIFY)
- else:
- self.logger.log_passed("SMM_Code_Chk_En is enabled and locked down")
-
- returnself.rc_res.getReturnCode(res)
-
- # --------------------------------------------------------------------------
- # run( module_argv )
- # Required function: run here all tests from this module
- # --------------------------------------------------------------------------
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-2022, 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
-#
-
-"""
-SMM TSEG Range Configuration Checks
-
-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.
-
-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.
-
-References:
- - `System Management Mode Design and Security Issues <http://www.ssi.gouv.fr/uploads/IMG/pdf/IT_Defense_2010_final.pdf>`_
- - `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>`_
-
-Usage:
- ``chipsec_main -m smm_dma``
-
-Examples:
- >>> chipsec_main.py -m smm_dma
-
-Registers used:
- - TSEGBaseLock (control)
- - TSEGLimitLock (control)
- - MSR_BIOS_DONE.IA_UNTRUSTED
- - PCI0.0.0_TSEGMB.TSEGMB
- - PCI0.0.0_BGSM.BGSM
- - IA32_SMRR_PHYSBASE.PhysBase
- - IA32_SMRR_PHYSMASK.PhysMask
-
-Supported Platforms:
- - Core (client)
-
-"""
-
-fromchipsec.module_commonimportBaseModule,ModuleResult,MTAG_SMM,MTAG_HWCONFIG
-fromtypingimportList
-
-_MODULE_NAME='smm_dma'
-
-TAGS=[MTAG_SMM,MTAG_HWCONFIG]
-
-
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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
-#
-
-
-"""
-CPU SMM Cache Poisoning / System Management Range Registers check
-
-This module checks to see that SMRRs are enabled and configured.
-
-Reference:
- Researchers demonstrated a way to use CPU cache to effectively change values in SMRAM in
- `Attacking SMM Memory via Intel CPU Cache Poisoning <http://www.invisiblethingslab.com/resources/misc09/smm_cache_fun.pdf>`_
- and `Getting into the SMRAM: SMM Reloaded <http://cansecwest.com/csw09/csw09-duflot.pdf>`_ .
- If ring 0 software can make SMRAM cacheable and then populate cache lines at SMBASE with exploit code,
- then when an SMI is triggered, the CPU could execute the exploit code from cache.
- System Management Mode Range Registers (SMRRs) force non-cachable behavior and block access to SMRAM when the CPU is not in SMM.
- These registers need to be enabled/configured by the BIOS.
-
-Usage:
- ``chipsec_main -m common.smrr [-a modify]``
-
- - ``-a modify``: Attempt to modify memory at SMRR base
-
-Examples:
- >>> chipsec_main.py -m common.smrr
- >>> chipsec_main.py -m common.smrr -a modify
-
-Registers used:
- - IA32_SMRR_PHYSBASE.PhysBase
- - IA32_SMRR_PHYSBASE.Type
- - IA32_SMRR_PHYSMASK.PhysMask
- - IA32_SMRR_PHYSMASK.Valid
-
-"""
-
-fromchipsec.module_commonimportBaseModule,ModuleResult,MTAG_BIOS,MTAG_SMM,OPT_MODIFY
-fromchipsec.hal.msrimportMemType
-fromtypingimportList
-
-TAGS=[MTAG_BIOS,MTAG_SMM]
-
-
-
[docs]defis_supported(self)->bool:
- mtrr_exist=self.cs.is_register_defined('MTRRCAP')
- pbase_exist=self.cs.is_register_defined('IA32_SMRR_PHYSBASE')
- pmask_exist=self.cs.is_register_defined('IA32_SMRR_PHYSMASK')
- ifmtrr_existandpbase_existandpmask_exist:
- returnTrue
- self.logger.log_information('Required registers are not defined for this platform. Skipping module.')
- self.rc_res.setStatusBit(self.rc_res.status.NOT_APPLICABLE)
- self.res=self.rc_res.getReturnCode(ModuleResult.NOTAPPLICABLE)
- returnFalse
-
- #
- # Check that SMRR are supported by CPU in IA32_MTRRCAP_MSR[SMRR]
- #
-
[docs]defcheck_SMRR(self,do_modify:bool)->int:
-
- ifself.cs.cpu.check_SMRR_supported():
- self.logger.log_good("OK. SMRR range protection is supported")
- else:
- self.logger.log_not_applicable("CPU does not support SMRR range protection of SMRAM")
- self.rc_res.setStatusBit(self.rc_res.status.NOT_APPLICABLE)
- self.res=self.rc_res.getReturnCode(ModuleResult.NOTAPPLICABLE)
- #
- # SMRR are supported
- #
- smrr_ok=True
-
- #
- # 2. Check SMRR_BASE is programmed correctly (on CPU0)
- #
- self.logger.log('')
- self.logger.log("[*] Checking SMRR range base programming..")
- msr_smrrbase=self.cs.read_register('IA32_SMRR_PHYSBASE')
- self.cs.print_register('IA32_SMRR_PHYSBASE',msr_smrrbase)
- smrrbase=self.cs.get_register_field('IA32_SMRR_PHYSBASE',msr_smrrbase,'PhysBase',True)
- smrrtype=self.cs.get_register_field('IA32_SMRR_PHYSBASE',msr_smrrbase,'Type')
- self.logger.log(f"[*] SMRR range base: 0x{smrrbase:016X}")
-
- ifsmrrtypeinMemType:
- self.logger.log(f"[*] SMRR range memory type is {MemType[smrrtype]}")
- else:
- smrr_ok=False
- self.logger.log_bad(f"SMRR range memory type 0x{smrrtype:X} is invalid")
-
- if0==smrrbase:
- smrr_ok=False
- self.logger.log_bad("SMRR range base is not programmed")
-
- ifsmrr_ok:
- self.logger.log_good("OK so far. SMRR range base is programmed")
-
- #
- # 3. Check SMRR_MASK is programmed and SMRR are enabled (on CPU0)
- #
- self.logger.log('')
- self.logger.log("[*] Checking SMRR range mask programming..")
- msr_smrrmask=self.cs.read_register('IA32_SMRR_PHYSMASK')
- self.cs.print_register('IA32_SMRR_PHYSMASK',msr_smrrmask)
- smrrmask=self.cs.get_register_field('IA32_SMRR_PHYSMASK',msr_smrrmask,'PhysMask',True)
- smrrvalid=self.cs.get_register_field('IA32_SMRR_PHYSMASK',msr_smrrmask,'Valid')
- self.logger.log(f"[*] SMRR range mask: 0x{smrrmask:016X}")
-
- ifnot(smrrvalidand(0!=smrrmask)):
- smrr_ok=False
- self.logger.log_bad("SMRR range is not enabled")
-
- ifsmrr_ok:
- self.logger.log_good("OK so far. SMRR range is enabled")
-
- #
- # 4. Verify that SMRR_BASE/MASK MSRs have the same values on all logical CPUs
- #
- self.logger.log('')
- self.logger.log("[*] Verifying that SMRR range base & mask are the same on all logical CPUs..")
- fortidinrange(self.cs.msr.get_cpu_thread_count()):
- msr_base=self.cs.read_register('IA32_SMRR_PHYSBASE',tid)
- msr_mask=self.cs.read_register('IA32_SMRR_PHYSMASK',tid)
- self.logger.log(f"[CPU{tid:d}] SMRR_PHYSBASE = {msr_base:016X}, SMRR_PHYSMASK = {msr_mask:016X}")
- if(msr_base!=msr_smrrbase)or(msr_mask!=msr_smrrmask):
- smrr_ok=False
- self.logger.log_bad("SMRR range base/mask do not match on all logical CPUs")
- break
-
- ifsmrr_ok:
- self.logger.log_good("OK so far. SMRR range base/mask match on all logical CPUs")
-
- #
- # 5. Reading from & writing to SMRR_BASE physical address
- # writes should be dropped, reads should return all F's
- #
-
- self.logger.log(f"[*] Trying to read memory at SMRR base 0x{smrrbase:08X}..")
-
- ok=0xFFFFFFFF==self.cs.mem.read_physical_mem_dword(smrrbase)
- smrr_ok=smrr_okandok
- ifok:
- self.logger.log_passed("SMRR reads are blocked in non-SMM mode")# return all F's
- else:
- self.logger.log_failed("SMRR reads are not blocked in non-SMM mode")# all F's are not returned
-
- if(do_modify):
- self.logger.log(f"[*] Trying to modify memory at SMRR base 0x{smrrbase:08X}..")
- self.cs.mem.write_physical_mem_dword(smrrbase,0x90909090)
- ok=0x90909090!=self.cs.mem.read_physical_mem_dword(smrrbase)
- smrr_ok=smrr_okandok
- ifok:
- self.logger.log_good("SMRR writes are blocked in non-SMM mode")
- else:
- self.logger.log_bad("SMRR writes are not blocked in non-SMM mode")
-
- self.logger.log('')
- ifnotsmrr_ok:
- res=ModuleResult.FAILED
- self.rc_res.setStatusBit(self.rc_res.status.CONFIGURATION)
- self.logger.log_failed("SMRR protection against cache attack is not configured properly")
- else:
- res=ModuleResult.PASSED
- self.logger.log_passed("SMRR protection against cache attack is properly configured")
-
- returnself.rc_res.getReturnCode(res)
-
- # --------------------------------------------------------------------------
- # run( module_argv )
- # Required function: run here all tests from this module
- # --------------------------------------------------------------------------
-
[docs]defrun(self,module_argv:List[str])->int:
- self.logger.start_test("CPU SMM Cache Poisoning / System Management Range Registers")
- do_modify=(len(module_argv)>0)and(module_argv[0]==OPT_MODIFY)
- self.res=self.check_SMRR(do_modify)
- returnself.res
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2019, Eclypsium, Inc.
-# Copyright (c) 2019-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.
-
-"""
-This module checks that SPD Write Disable bit in SMBus controller has been set
-
-References:
- Intel 8 Series/C220 Series Chipset Family Platform Controller Hub datasheet
- Intel 300 Series Chipset Families Platform Controller Hub datasheet
-
-This module checks the following:
-
- SMBUS_HCFG.SPD_WD
-
-The module returns the following results:
-
- PASSED : SMBUS_HCFG.SPD_WD is set
-
- FAILED : SMBUS_HCFG.SPD_WD is not set and SPDs were detected
-
- INFORMATION: SMBUS_HCFG.SPD_WD is not set, but no SPDs were detected
-
-Hardware registers used:
-
- SMBUS_HCFG
-
-Usage:
- ``chipsec_main -m common.spd_wd``
-
-Examples:
- >>> chipsec_main.py -m common.spd_wd
-
-.. NOTE::
- This module will only run if:
- - SMBUS device is enabled
- - SMBUS_HCFG.SPD_WD is defined for the platform
-"""
-
-fromchipsec.module_commonimportBaseModule,ModuleResult
-fromchipsec.hal.smbusimportSMBus
-fromchipsec.hal.spdimportSPD
-fromtypingimportList
-
-
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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
-#
-#
-# Authors:
-# Yuriy Bulygin
-# Erik Bjorge
-#
-
-
-"""
-SPI Flash Region Access Control
-
-Checks SPI Flash Region Access Permissions programmed in the Flash Descriptor
-
-Usage:
- ``chipsec_main -m common.spi_access``
-
-Examples:
- >>> chipsec_main.py -m common.spi_access
-
-Registers used:
- - HSFS.FDV
- - FRAP.BRWA
-
-.. important::
- - Some platforms may use alternate means of protecting these regions.
- Consider this when assessing results.
-
-"""
-
-fromchipsec.module_commonimportBaseModule,ModuleResult,MTAG_BIOS
-fromchipsec.hal.spiimportSPI,GBE,PLATFORM_DATA,ME,FLASH_DESCRIPTOR
-fromtypingimportList
-
-TAGS=[MTAG_BIOS]
-
-
-
[docs]defis_supported(self)->bool:
- ifself.cs.register_has_field('HSFS','FDV')andself.cs.register_has_field('FRAP','BRWA'):
- returnTrue
- self.logger.log_important('HSFS.FDV or FRAP.BRWA registers not defined for platform. Skipping module.')
- self.rc_res.setStatusBit(self.rc_res.status.NOT_APPLICABLE)
- self.res=self.rc_res.getReturnCode(ModuleResult.NOTAPPLICABLE)
- returnFalse
-
- ##
- # Displays the SPI Regions Access Permissions
-
[docs]defcheck_flash_access_permissions(self)->int:
-
- res=ModuleResult.PASSED
- fdv=self.cs.read_register_field('HSFS','FDV')==1
- frap=self.cs.read_register('FRAP')
- brwa=self.cs.get_register_field('FRAP',frap,'BRWA')
-
- # Informational
- # State of Flash Descriptor Valid bit
- ifnotfdv:
- self.logger.log("[*] Flash Descriptor Valid bit is not set")
-
- # CPU/Software access to Platform Data region (platform specific)
- ifbrwa&(1<<PLATFORM_DATA):
- self.logger.log("[*] Software has write access to Platform Data region in SPI flash (it's platform specific)")
-
- # Warnings
- # CPU/Software access to GBe region
- ifbrwa&(1<<GBE):
- res=ModuleResult.WARNING
- self.rc_res.setStatusBit(self.rc_res.status.ACCESS_RW)
- self.logger.log_warning("Software has write access to GBe region in SPI flash")
-
- # Failures
- # CPU/Software access to Flash Descriptor region (Read Only)
- ifbrwa&(1<<FLASH_DESCRIPTOR):
- res=ModuleResult.FAILED
- self.rc_res.setStatusBit(self.rc_res.status.ACCESS_RW)
- self.logger.log_bad("Software has write access to SPI flash descriptor")
-
- # CPU/Software access to Intel ME region (Read Only)
- ifbrwa&(1<<ME):
- res=ModuleResult.FAILED
- self.rc_res.setStatusBit(self.rc_res.status.ACCESS_RW)
- self.logger.log_bad("Software has write access to Management Engine (ME) region in SPI flash")
-
- iffdv:
- ifModuleResult.PASSED==res:
- self.logger.log_passed("SPI Flash Region Access Permissions in flash descriptor look ok")
- elifModuleResult.FAILED==res:
- self.logger.log_failed("SPI Flash Region Access Permissions are not programmed securely in flash descriptor")
- self.logger.log_important('System may be using alternative protection by including descriptor region in SPI Protected Range Registers')
- self.logger.log_important('If using alternative protections, this can be considered a WARNING')
- elifModuleResult.WARNING==res:
- self.logger.log_warning("Certain SPI flash regions are writeable by software")
- else:
- res=ModuleResult.WARNING
- self.rc_res.setStatusBit(self.rc_res.status.UNSUPPORTED_FEATURE)
- self.logger.log_warning("Either flash descriptor is not valid or not present on this system")
-
- returnself.rc_res.getReturnCode(res)
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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
-#
-
-
-"""
-The SPI Flash Descriptor indicates read/write permissions for devices to access regions of the flash memory.
-This module simply reads the Flash Descriptor and checks that software cannot modify the Flash Descriptor itself.
-If software can write to the Flash Descriptor, then software could bypass any protection defined by it.
-While often used for debugging, this should not be the case on production systems.
-
-This module checks that software cannot write to the flash descriptor.
-
-Usage:
- ``chipsec_main -m common.spi_desc``
-
-Examples:
- >>> chipsec_main.py -m common.spi_desc
-
-Registers used:
- - FRAP.BRRA
- - FRAP.BRWA
-
-"""
-
-fromchipsec.module_commonimportBaseModule,ModuleResult,MTAG_BIOS
-fromchipsec.hal.spiimportFLASH_DESCRIPTOR
-fromtypingimportList
-
-TAGS=[MTAG_BIOS]
-
-
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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
-#
-
-"""
-Checks for SPI Controller Flash Descriptor Security Override Pin Strap (FDOPSS).
-On some systems, this may be routed to a jumper on the motherboard.
-
-Usage:
- ``chipsec_main -m common.spi_fdopss``
-
-Examples:
- >>> chipsec_main.py -m common.spi_fdopss
-
-Registers used:
- - HSFS.FDOPSS
-
-"""
-
-fromchipsec.module_commonimportBaseModule,ModuleResult,MTAG_BIOS
-fromtypingimportList
-
-TAGS=[MTAG_BIOS]
-
-
-
[docs]defis_supported(self)->bool:
- ifnotself.cs.register_has_field('HSFS','FDOPSS'):
- self.logger.log_important('HSFS.FDOPSS field not defined for platform. Skipping module.')
- self.rc_res.setStatusBit(self.rc_res.status.NOT_APPLICABLE)
- self.res=self.rc_res.getReturnCode(ModuleResult.NOTAPPLICABLE)
- returnFalse
- returnTrue
-
- # --------------------------------------------------------------------------
- # run( module_argv )
- # Required function: run here all tests from this module
- # --------------------------------------------------------------------------
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-2020, 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
-#
-
-"""
-The configuration of the SPI controller, including protected ranges (PR0-PR4), is locked by HSFS[FLOCKDN] until reset.
-If not locked, the controller configuration may be bypassed by reprogramming these registers.
-
-This vulnerability (not setting FLOCKDN) is also checked by other tools, including `flashrom <http://www.flashrom.org/>`_
-and Copernicus by MITRE.
-
-This module checks that the SPI Flash Controller configuration is locked.
-
-Reference:
- - `flashrom <http://www.flashrom.org/>`_
- - `Copernicus: Question Your Assumptions about BIOS Security <http://www.mitre.org/capabilities/cybersecurity/overview/cybersecurity-blog/copernicus-question-your-assumptions-about>`_
-
-Usage:
- ``chipsec_main -m common.spi_lock``
-
-Examples:
- >>> chipsec_main.py -m common.spi_lock
-
-Registers used:
- - FlashLockDown (control)
- - SpiWriteStatusDis (control)
-
-"""
-
-fromchipsec.module_commonimportBaseModule,ModuleResult,MTAG_BIOS
-fromtypingimportList
-
-TAGS=[MTAG_BIOS]
-
-
-
Source code for chipsec.modules.common.uefi.access_uefispec
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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
-#
-
-
-"""
-Checks protection of UEFI variables defined in the UEFI spec to have certain permissions.
-
-Returns failure if variable attributes are not as defined in `table 11 "Global Variables" <http://uefi.org/>`_ of the UEFI spec.
-
-usage:
- ``chipsec_main -m common.uefi.access_uefispec [-a modify]``
-
- - ``-a modify``: Attempt to modify each variable in addition to checking attributes
-
-Where:
- - ``[]``: optional line
-
-Examples:
- >>> chipsec_main.py -m common.uefi.access_uefispec
- >>> chipsec_main.py -m common.uefi.access_uefispec -a modify
-
-NOTE:
-Requires an OS with UEFI Runtime API support.
-"""
-
-fromchipsec.module_commonimportBaseModule,ModuleResult,MTAG_SECUREBOOT,MTAG_BIOS,OPT_MODIFY
-fromchipsec.hal.uefiimportUEFI,EFI_VARIABLE_NON_VOLATILE,EFI_VARIABLE_BOOTSERVICE_ACCESS,EFI_VARIABLE_RUNTIME_ACCESS,get_attr_string
-fromchipsec.hal.uefiimportEFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS,EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS,EFI_VARIABLE_APPEND_WRITE
-fromchipsec.hal.uefi_commonimportStatusCode
-fromtypingimportList
-
-
-TAGS=[MTAG_BIOS,MTAG_SECUREBOOT]
-
-
-
Source code for chipsec.modules.common.uefi.s3bootscript
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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
-#
-
-
-"""
-Checks protections of the S3 resume boot-script implemented by the UEFI based firmware
-
-References:
-
-`VU#976132 UEFI implementations do not properly secure the EFI S3 Resume Boot Path boot script <https://www.kb.cert.org/vuls/id/976132>`_
-
-`Technical Details of the S3 Resume Boot Script Vulnerability <http://www.intelsecurity.com/advanced-threat-research/content/WP_Intel_ATR_S3_ResBS_Vuln.pdf>`_ by Intel Security's Advanced Threat Research team.
-
-`Attacks on UEFI Security <https://events.ccc.de/congress/2014/Fahrplan/system/attachments/2557/original/AttacksOnUEFI_Slides.pdf>`_ by Rafal Wojtczuk and Corey Kallenberg.
-
-`Attacking UEFI Boot Script <https://bromiumlabs.files.wordpress.com/2015/01/venamis_whitepaper.pdf>`_ by Rafal Wojtczuk and Corey Kallenberg.
-
-`Exploiting UEFI boot script table vulnerability <http://blog.cr4.sh/2015/02/exploiting-uefi-boot-script-table.html>`_ by Dmytro Oleksiuk.
-
-Usage:
- ``chipsec_main.py -m common.uefi.s3bootscript [-a <script_address>]``
-
- - ``-a <script_address>``: Specify the bootscript address
-
-Where:
- - ``[]``: optional line
-
-Examples:
- >>> chipsec_main.py -m common.uefi.s3bootscript
- >>> chipsec_main.py -m common.uefi.s3bootscript -a 0x00000000BDE10000
-
-.. NOTE::
- Requires an OS with UEFI Runtime API support.
-"""
-
-fromchipsec.module_commonimportBaseModule,ModuleResult,MTAG_BIOS,MTAG_SMM,MTAG_SECUREBOOT
-fromchipsec.definesimportBOUNDARY_1MB,BOUNDARY_4GB
-fromchipsec.hal.uefiimportUEFI,parse_script
-fromchipsec.hal.uefi_commonimportS3BootScriptOpcode,S3BOOTSCRIPT_ENTRY
-fromtypingimportList
-
-TAGS=[MTAG_BIOS,MTAG_SMM,MTAG_SECUREBOOT]
-
-########################################################################################################
-#
-# Main module functionality
-#
-########################################################################################################
-BOOTSCRIPT_OK=0x0
-BOOTSCRIPT_INSIDE_SMRAM=0x1
-BOOTSCRIPT_OUTSIDE_SMRAM=0x2
-DISPATCH_OPCODES_UNPROTECTED=0x4
-DISPATCH_OPCODES_PROTECTED=0x8
-
-HIGH_BIOS_RANGE_SIZE=2*BOUNDARY_1MB
-
-
-
[docs]defcheck_s3_bootscript(self,bootscript_pa:int)->int:
- res=BOOTSCRIPT_OK
- self.logger.log(f"[*] Checking S3 boot-script at 0x{bootscript_pa:016X}")
-
- # Checking if it's in SMRAM
- scriptInsideSMRAM=self.is_inside_SMRAM(bootscript_pa)
- ifscriptInsideSMRAM:
- res|=BOOTSCRIPT_INSIDE_SMRAM
- self.logger.log_good('S3 boot-script is in SMRAM')
- self.logger.log_important("Note: the test could not verify Dispatch opcodes because the script is in SMRAM. Entry-points of Dispatch opcodes also need to be protected.")
- else:
- res|=BOOTSCRIPT_OUTSIDE_SMRAM
- self.logger.log_bad('S3 boot-script is not in SMRAM')
- self.logger.log('[*] Reading S3 boot-script from memory..')
- script_all=self.cs.mem.read_physical_mem(bootscript_pa,0x100000)
- self.logger.log('[*] Decoding S3 boot-script opcodes..')
- script_entries=parse_script(script_all,False)
- dispatch_opcodes_ok=self.check_dispatch_opcodes(script_entries)
- ifdispatch_opcodes_ok:
- res|=DISPATCH_OPCODES_PROTECTED
- self.logger.log_important("S3 boot-script is not in protected memory but didn't find unprotected Dispatch entry-points")
- else:
- res|=DISPATCH_OPCODES_UNPROTECTED
- self.logger.log_bad('Entry-points of Dispatch opcodes in S3 boot-script are not in protected memory')
- returnres
-
-
[docs]defcheck_s3_bootscripts(self,bsaddress=None)->int:
- res=0
- scriptInsideSMRAM=False
-
- ifbsaddress:
- bootscript_PAs=[bsaddress]
- else:
- found,bootscript_PAs=self._uefi.find_s3_bootscript()
- ifnotfound:
- self.logger.log_good("Didn't find any S3 boot-scripts in EFI variables")
- self.logger.log_warning("S3 Boot-Script was not found. Firmware may be using other ways to store/locate it, or OS might be blocking access.")
- self.rc_res.setStatusBit(self.rc_res.status.VERIFY)
- returnself.rc_res.getReturnCode(ModuleResult.WARNING)
-
-
- self.logger.log_important(f'Found {len(bootscript_PAs):d} S3 boot-script(s) in EFI variables')
-
- forbootscript_painbootscript_PAs:
- if0==bootscript_pa:
- continue
- res|=self.check_s3_bootscript(bootscript_pa)
-
- self.logger.log('')
-
- if(res&BOOTSCRIPT_OUTSIDE_SMRAM)!=0:
- # BOOTSCRIPT_OUTSIDE_SMRAM
- if(res&DISPATCH_OPCODES_UNPROTECTED)!=0:
- # DISPATCH_OPCODES_UNPROTECTED
- status=ModuleResult.FAILED
- self.rc_res.setStatusBit(self.rc_res.status.PROTECTION)
- self.logger.log_failed('S3 Boot-Script and Dispatch entry-points do not appear to be protected')
- else:
- # DISPATCH_OPCODES_PROTECTED
- status=ModuleResult.WARNING
- self.rc_res.setStatusBit(self.rc_res.status.VERIFY)
- self.logger.log_warning('S3 Boot-Script is not in SMRAM but Dispatch entry-points appear to be protected. Recommend further testing')
- else:
- # BOOTSCRIPT_INSIDE_SMRAM
- status=ModuleResult.WARNING
- self.rc_res.setStatusBit(self.rc_res.status.VERIFY)
- self.logger.log_warning("S3 Boot-Script is inside SMRAM. The script is protected but Dispatch opcodes cannot be inspected")
-
- self.logger.log_important("Additional testing of the S3 boot-script can be done using tools.uefi.s3script_modify")
-
- returnstatus
-
-
[docs]defrun(self,module_argv:List[str])->int:
- self.logger.start_test("S3 Resume Boot-Script Protections")
-
- iflen(module_argv)>2:
- self.logger.log_error('Expected module options: -a <bootscript_address>')
- self.rc_res.setStatusBit(self.rc_res.status.UNSUPPORTED_OPTION)
- returnself.rc_res.getReturnCode(ModuleResult.ERROR)
-
- script_pa=None
-
- iflen(module_argv)>0:
- script_pa=int(module_argv[0],16)
- self.logger.log(f'[*] Using manually assigned S3 Boot-Script table base: 0x{script_pa:016X}')
- (self.smrambase,self.smramlimit,self.smramsize)=self.cs.cpu.get_SMRAM()
- if(self.smrambaseisnotNone)and(self.smramlimitisnotNone):
- self.logger.log(f'[*] SMRAM: Base = 0x{self.smrambase:016X}, Limit = 0x{self.smramlimit:016X}, Size = 0x{self.smramsize:08X}')
-
- try:
- ifscript_paisnotNone:
- self.res=self.check_s3_bootscripts(script_pa)
- else:
- self.res=self.check_s3_bootscripts()
- except:
- self.logger.log_error("The module was not able to recognize the S3 resume boot script on this platform.")
- ifself.logger.VERBOSE:
- raise
- self.res=ModuleResult.ERROR
-
- returnself.rc_res.getReturnCode(self.res)
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2023, 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
-#
-
-importos
-importconfigparser
-fromchipsec.fileimportget_main_dir
-fromchipsec.exceptionsimportCSConfigError
-
-
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2023, 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
-
-fromcollectionsimportnamedtuple
-fromenumimportEnum
-fromchipsec.loggerimportlogger
-
-
-
-
-
-# Stage - None
-# - Never runs
-# - stage_data - None
-# - Returns None
-
-# Stage.GET_INFO
-# - Gathers platform information including values used in platform detection
-# - stage_data - stage_info named tuple
-# - Returns - info_data named tuple
-stage_info=namedtuple('StageInfo',['vid_str','configuration'])
-info_data=namedtuple('InfoData',['family','proc_code','pch_code','detect_vals','req_pch','vid_str','sku_list'])
-
-# Stage.DEVICE_CFG
-# - Determine device configuration files
-# - stage_data - stage_dev named tuple for file being processed
-# - Returns - A list of config_data named tuples
-stage_dev=namedtuple('StageCore',['vid_str','xml_file'])
-config_data=namedtuple('DevData',['vid_str','dev_name','xml_file'])
-
-# Stage.CORE_SUPPORT
-# - Parse all core XML tags and update configuration data directly in object
-# - stage_data - config_data named tuple for the file being processed
-# - Returns - None
-
-# Stage.CUST_SUPPORT
-# - Parse any custom XML tags and update configuration data directly in object
-# - stage_data - config_data named tuple for the file being processed
-# - Returns - None
-
-
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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
-#
-
-
-"""
-Command-line utility providing access to ACPI tables
-
->>> chipsec_util acpi list
->>> chipsec_util acpi table <name>|<file_path>
-
-Examples:
-
->>> chipsec_util acpi list
->>> chipsec_util acpi table XSDT
->>> chipsec_util acpi table acpi_table.bin
-"""
-
-fromos.pathimportexistsaspath_exists
-fromargparseimportArgumentParser
-
-fromchipsec.hal.acpiimportACPI
-fromchipsec.commandimportBaseCommand,toLoad
-
-# ###################################################################
-#
-# Advanced Configuration and Power Interface (ACPI)
-#
-# ###################################################################
-
-
-
[docs]defrequirements(self)->toLoad:
- ifself.func==self.acpi_tableandself._file:
- returntoLoad.Nil# TODO: Fix this case. Need to update ACPI HAL to not try to auto-populate tables.
- returntoLoad.All
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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
-#
-
-
-"""
-usage as a standalone utility:
- >>> chipsec_util platform
-"""
-
-fromchipsec.commandimportBaseCommand,toLoad
-fromchipsec.exceptionsimportUnknownChipsetError
-
-# ###################################################################
-#
-# Chipset/CPU Detection
-#
-# ###################################################################
-
-
-
-# !/usr/bin/python
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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 cmos dump
->>> chipsec_util cmos readl|writel|readh|writeh <byte_offset> [byte_val]
-
-Examples:
-
->>> chipsec_util cmos dump
->>> chipsec_util cmos readl 0x0
->>> chipsec_util cmos writeh 0x0 0xCC
-"""
-
-fromargparseimportArgumentParser
-
-fromchipsec.commandimportBaseCommand,toLoad
-fromchipsec.hal.cmosimportCMOS
-fromchipsec.exceptionsimportCmosRuntimeError
-
-
-
-# !/usr/bin/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 config show [config] <name>
-
-Examples:
-
->>> chipsec_util config show ALL
->>> chipsec_util config show MMIO_BARS
->>> chipsec_util config show REGISTERS BC
-"""
-
-fromargparseimportArgumentParser
-
-fromchipsec.commandimportBaseCommand,toLoad
-fromtypingimportAny,Dict
-
-
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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 cpu info
->>> chipsec_util cpu cr <thread> <cr_number> [value]
->>> chipsec_util cpu cpuid <eax> [ecx]
->>> chipsec_util cpu pt [paging_base_cr3]
->>> chipsec_util cpu topology
-
-Examples:
-
->>> chipsec_util cpu info
->>> chipsec_util cpu cr 0 0
->>> chipsec_util cpu cr 0 4 0x0
->>> chipsec_util cpu cpuid 0x40000000
->>> chipsec_util cpu pt
->>> chipsec_util cpu topology
-"""
-
-fromargparseimportArgumentParser
-
-fromchipsec.commandimportBaseCommand,toLoad
-fromtypingimportDict,List,Optional,Union
-
-# ###################################################################
-#
-# CPU utility
-#
-# ###################################################################
-
-
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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 can parse an image file containing data from the SPI flash (such as the result of chipsec_util spi dump). This can be critical in forensic analysis.
-
-This will create multiple log files, binaries, and directories that correspond to the sections, firmware volumes, files, variables, etc. stored in the SPI flash.
-
-Usage:
-
- >>> chipsec_util decode <rom> [fw_type]
-
-For a list of fw types run:
-
- >>> chipsec_util decode types
-
-Examples:
-
- >>> chipsec_util decode spi.bin vss
-
-.. note::
- - It may be necessary to try various options for fw_type in order to correctly parse NVRAM variables.
- Currently, CHIPSEC does not autodetect the correct format.
- If the nvram directory does not appear and the list of nvram variables is empty, try again with another type.
-
-"""
-
-importos
-fromargparseimportArgumentParser
-
-fromchipsec.fileimportread_file,write_file
-fromchipsec.commandimportBaseCommand,toLoad
-
-fromchipsec.hal.spiimportFLASH_DESCRIPTOR,BIOS
-fromchipsec.hal.spi_descriptorimportget_spi_flash_descriptor,get_spi_regions,parse_spi_flash_descriptor
-fromchipsec.hal.spi_uefiimportdecode_uefi_region
-fromchipsec.hal.uefiimportuefi_platform
-
-
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2018-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 deltas <previous> <current> [out-format] [out-name]
-
-out-format - JSON | XML
-out-name - Output file name
-
-Example:
->>> chipsec_util deltas run1.json run2.json
-
-"""
-
-fromtimeimporttime
-fromargparseimportArgumentParser
-
-fromchipsec.commandimportBaseCommand,toLoad
-importchipsec.result_deltas
-fromchipsec.optionsimportOptions
-
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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
-#
-
-"""
-The idt, gdt and ldt commands print the IDT, GDT and LDT, respectively.
-
-IDT command:
-
->>> chipsec_util idt [cpu_id]
-
-Examples:
-
->>> chipsec_util idt 0
->>> chipsec_util idt
-
-GDT command:
-
->>> chipsec_util gdt [cpu_id]
-
-Examples:
-
->>> chipsec_util gdt 0
->>> chipsec_util gdt
-
-LDT command:
-
->>> chipsec_util ldt [cpu_id]
-
-Examples:
-
->>> chipsec_util ldt 0
->>> chipsec_util ldt
-"""
-
-fromargparseimportArgumentParser
-
-fromchipsec.commandimportBaseCommand,toLoad
-
-# CPU descriptor tables
-
-
-
-# !/usr/bin/python
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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 ec dump [<size>]
->>> chipsec_util ec command <command>
->>> chipsec_util ec read <offset> [<size>]
->>> chipsec_util ec write <offset> <byte_val>
->>> chipsec_util ec index [<offset>]
-
-Examples:
-
->>> chipsec_util ec dump
->>> chipsec_util ec command 0x001
->>> chipsec_util ec read 0x2F
->>> chipsec_util ec write 0x2F 0x00
->>> chipsec_util ec index
-"""
-
-fromargparseimportArgumentParser
-
-fromchipsec.commandimportBaseCommand,toLoad
-
-fromchipsec.loggerimportprint_buffer_bytes
-fromchipsec.hal.ecimportEC
-
-
-# Embedded Controller
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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
-#
-
-
-"""
-The igd command allows memory read/write operations using igd dma.
-
->>> chipsec_util igd
->>> chipsec_util igd dmaread <address> [width] [file_name]
->>> chipsec_util igd dmawrite <address> <width> <value|file_name>
-
-Examples:
-
->>> chipsec_util igd dmaread 0x20000000 4
->>> chipsec_util igd dmawrite 0x2217F1000 0x4 deadbeef
-"""
-
-fromchipsec.commandimportBaseCommand,toLoad
-fromchipsec.loggerimportprint_buffer_bytes
-fromargparseimportArgumentParser
-fromchipsec.fileimportread_file,write_file
-fromchipsec.halimportigd
-importos
-
-
-# Port I/O
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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
-#
-
-"""
-SMI command:
-
->>> chipsec_util smi count
->>> chipsec_util smi send <thread_id> <SMI_code> <SMI_data> [RAX] [RBX] [RCX] [RDX] [RSI] [RDI]
->>> chipsec_util smi smmc <RT_code_start> <RT_code_end> <GUID> <payload_loc> <payload_file|payload_string> [port]
-
-Examples:
-
->>> chipsec_util smi count
->>> chipsec_util smi send 0x0 0xDE 0x0
->>> chipsec_util smi send 0x0 0xDE 0x0 0xAAAAAAAAAAAAAAAA ..
->>> chipsec_util smi smmc 0x79dfe000 0x79efdfff ed32d533-99e6-4209-9cc02d72cdd998a7 0x79dfaaaa payload.bin
-
-NMI command:
-
->>> chipsec_util nmi
-
-Examples:
-
->>> chipsec_util nmi
-"""
-
-importos
-
-fromchipsec.commandimportBaseCommand,toLoad
-fromchipsec.hal.interruptsimportInterrupts
-fromchipsec.hal.uefi_commonimportEFI_ERROR_STR
-fromargparseimportArgumentParser
-
-
-# ###################################################################
-#
-# CPU Interrupts
-#
-# ###################################################################
-
-
-
-# !/usr/bin/python
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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
-#
-
-
-"""
-The io command allows direct access to read and write I/O port space.
-
->>> chipsec_util io list
->>> chipsec_util io read <io_port> <width>
->>> chipsec_util io write <io_port> <width> <value>
-
-Examples:
-
->>> chipsec_util io list
->>> chipsec_util io read 0x61 1
->>> chipsec_util io write 0x430 1 0x0
-"""
-
-fromargparseimportArgumentParser
-
-fromchipsec.halimportiobar
-fromchipsec.commandimportBaseCommand,toLoad
-fromchipsec.exceptionsimportIOBARRuntimeError
-
-
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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
-#
-
-
-"""
-Command-line utility providing access to IOMMU engines
-
->>> chipsec_util iommu list
->>> chipsec_util iommu config [iommu_engine]
->>> chipsec_util iommu status [iommu_engine]
->>> chipsec_util iommu enable|disable <iommu_engine>
->>> chipsec_util iommu pt
-
-Examples:
-
->>> chipsec_util iommu list
->>> chipsec_util iommu config VTD
->>> chipsec_util iommu status GFXVTD
->>> chipsec_util iommu enable VTD
->>> chipsec_util iommu pt
-"""
-
-fromchipsec.commandimportBaseCommand,toLoad
-fromchipsec.halimportacpi,iommu
-fromargparseimportArgumentParser
-fromchipsec.exceptionsimportIOMMUError,AcpiRuntimeError
-
-
-# I/O Memory Management Unit (IOMMU), e.g. Intel VT-d
-
[docs]defiommu_list(self)->None:
- self.logger.log("[CHIPSEC] Enumerating supported IOMMU engine names:")
- self.logger.log(f'{list(iommu.IOMMU_ENGINES.keys())}')
- self.logger.log_important('\nNote: These are the IOMMU engine names supported by iommu_cmd.')
- self.logger.log_important('It does not mean they are supported/enabled in the current platform.')
-# 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
-
-"""
-
-fromargparseimportArgumentParser
-
-fromchipsec.commandimportBaseCommand,toLoad
-fromchipsec.hal.locksimportlocks,LockResult
-fromchipsec.definesimportis_set
-
-
-
[docs]deflog_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""")
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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
-#
-
-
-"""
-The mem command provides direct access to read and write physical memory.
-
->>> chipsec_util mem <op> <physical_address> <length> [value|buffer_file]
->>> <physical_address> : 64-bit physical address
->>> <op> : read|readval|write|writeval|allocate|pagedump|search
->>> <length> : byte|word|dword or length of the buffer from <buffer_file>
->>> <value> : byte, word or dword value to be written to memory at <physical_address>
->>> <buffer_file> : file with the contents to be written to memory at <physical_address>
-
-Examples:
-
->>> chipsec_util mem <op> <physical_address> <length> [value|file]
->>> chipsec_util mem readval 0xFED40000 dword
->>> chipsec_util mem read 0x41E 0x20 buffer.bin
->>> chipsec_util mem writeval 0xA0000 dword 0x9090CCCC
->>> chipsec_util mem write 0x100000000 0x1000 buffer.bin
->>> chipsec_util mem write 0x100000000 0x10 000102030405060708090A0B0C0D0E0F
->>> chipsec_util mem allocate 0x1000
->>> chipsec_util mem pagedump 0xFED00000 0x100000
->>> chipsec_util mem search 0xF0000 0x10000 _SM_
-"""
-
-importos
-
-fromchipsec.commandimportBaseCommand,toLoad
-fromchipsec.definesimportALIGNED_4KB,BOUNDARY_4KB,bytestostring
-fromchipsec_utilimportget_option_width,is_option_valid_width,CMD_OPTS_WIDTH
-fromchipsec.fileimportread_file,write_file,get_main_dir
-fromchipsec.loggerimportprint_buffer_bytes
-fromargparseimportArgumentParser
-
-# Physical Memory
-
-
-
[docs]defmem_allocate(self)->None:
- (va,pa)=self.cs.mem.alloc_physical_mem(self.allocate_length)
- self.logger.log(f'[CHIPSEC] Allocated {self.allocate_length:X} bytes of physical memory: VA = 0x{va:016X}, PA = 0x{pa:016X}')
-
-
[docs]defmem_search(self)->None:
- buffer=self.cs.mem.read_physical_mem(self.phys_address,self.length)
- buffer=bytestostring(buffer)
- offset=buffer.find(self.value)
-
- if(offset!=-1):
- self.logger.log(f'[CHIPSEC] Search buffer from memory: PA = 0x{self.phys_address:016X}, len = 0x{self.length:X}, target address= 0x{self.phys_address+offset:X}..')
- else:
- self.logger.log(f'[CHIPSEC] Search buffer from memory: PA = 0x{self.phys_address:016X}, len = 0x{self.length:X}, can not find the target in the searched range..')
-# 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
-#
-
-
-"""
-The mmcfg_base command displays PCIe MMCFG Base/Size.
-
-Usage:
-
->>> chipsec_util mmcfg_base
-
-Examples:
-
->>> chipsec_util mmcfg_base
-"""
-
-fromchipsec.commandimportBaseCommand,toLoad
-fromchipsec.halimportmmio
-
-
-# Access to Memory Mapped PCIe Configuration Space (MMCFG)
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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
-#
-
-
-"""
-The mmcfg command allows direct access to memory mapped config space.
-
->>> chipsec_util mmcfg base
->>> chipsec_util mmcfg read <bus> <device> <function> <offset> <width>
->>> chipsec_util mmcfg write <bus> <device> <function> <offset> <width> <value>
->>> chipsec_util mmcfg ec
-
-
-Examples:
-
->>> chipsec_util mmcfg base
->>> chipsec_util mmcfg read 0 0 0 0x200 4
->>> chipsec_util mmcfg write 0 0 0 0x200 1 0x1A
->>> chipsec_util mmcfg ec
-"""
-
-fromchipsec.commandimportBaseCommand,toLoad
-fromargparseimportArgumentParser
-
-
-# Access to Memory Mapped PCIe Configuration Space (MMCFG)
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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 mmio list
->>> chipsec_util mmio dump <MMIO_BAR_name> [offset] [length]
->>> chipsec_util mmio dump-abs <MMIO_base_address> [offset] [length]
->>> chipsec_util mmio read <MMIO_BAR_name> <offset> <width>
->>> chipsec_util mmio read-abs <MMIO_base_address> <offset> <width>
->>> chipsec_util mmio write <MMIO_BAR_name> <offset> <width> <value>
->>> chipsec_util mmio write-abs <MMIO_base_address> <offset> <width> <value>
-
-Examples:
-
->>> chipsec_util mmio list
->>> chipsec_util mmio dump MCHBAR
->>> chipsec_util mmio dump-abs 0xFE010000 0x70 0x10
->>> chipsec_util mmio read SPIBAR 0x74 0x4
->>> chipsec_util mmio read-abs 0xFE010000 0x74 0x04
->>> chipsec_util mmio write SPIBAR 0x74 0x4 0xFFFF0000
->>> chipsec_util mmio write-abs 0xFE010000 0x74 0x04 0xFFFF0000
-"""
-
-fromchipsec.commandimportBaseCommand,toLoad
-fromchipsec.halimportmmio
-fromargparseimportArgumentParser
-
-
-# ###################################################################
-#
-# Access to Memory Mapped PCIe Configuration Space (MMCFG)
-#
-# ###################################################################
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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 msgbus read <port> <register>
->>> chipsec_util msgbus write <port> <register> <value>
->>> chipsec_util msgbus mm_read <port> <register>
->>> chipsec_util msgbus mm_write <port> <register> <value>
->>> chipsec_util msgbus message <port> <register> <opcode> [value]
->>>
->>> <port> : message bus port of the target unit
->>> <register>: message bus register/offset in the target unit port
->>> <value> : value to be written to the message bus register/offset
->>> <opcode> : opcode of the message on the message bus
-
-Examples:
-
->>> chipsec_util msgbus read 0x3 0x2E
->>> chipsec_util msgbus mm_write 0x3 0x27 0xE0000001
->>> chipsec_util msgbus message 0x3 0x2E 0x10
->>> chipsec_util msgbus message 0x3 0x2E 0x11 0x0
-"""
-
-fromchipsec.commandimportBaseCommand,toLoad
-fromargparseimportArgumentParser
-
-
-# Message Bus
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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
-#
-
-
-"""
-The msr command allows direct access to read and write MSRs.
-
->>> chipsec_util msr <msr> [eax] [edx] [thread_id]
-
-Examples:
-
->>> chipsec_util msr 0x3A
->>> chipsec_util msr 0x3A 0x0
->>> chipsec_util msr 0x8B 0x0 0x0 0x0
-"""
-
-fromchipsec.commandimportBaseCommand,toLoad
-fromargparseimportArgumentParser
-
-
-# CPU Model Specific Registers
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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
-#
-
-
-"""
-The pci command can enumerate PCI/PCIe devices, enumerate expansion ROMs and allow direct access to PCI configuration registers via bus/device/function.
-
->>> chipsec_util pci enumerate
->>> chipsec_util pci read <bus> <device> <function> <offset> [width]
->>> chipsec_util pci write <bus> <device> <function> <offset> <width> <value>
->>> chipsec_util pci dump [<bus>] [<device>] [<function>]
->>> chipsec_util pci xrom [<bus>] [<device>] [<function>] [xrom_address]
->>> chipsec_util pci cmd [mask] [class] [subclass]
-
-Examples:
-
->>> chipsec_util pci enumerate
->>> chipsec_util pci read 0 0 0 0x00
->>> chipsec_util pci read 0 0 0 0x88 byte
->>> chipsec_util pci write 0 0x1F 0 0xDC 1 0x1
->>> chipsec_util pci write 0 0 0 0x98 dword 0x004E0040
->>> chipsec_util pci dump
->>> chipsec_util pci dump 0 0 0
->>> chipsec_util pci xrom
->>> chipsec_util pci xrom 3 0 0 0xFEDF0000
->>> chipsec_util pci cmd
->>> chipsec_util pci cmd 1
-"""
-
-fromchipsec.commandimportBaseCommand,toLoad
-fromchipsec.loggerimportpretty_print_hex_buffer
-fromargparseimportArgumentParser
-fromchipsec_utilimportget_option_width,is_option_valid_width,CMD_OPTS_WIDTH
-fromchipsec.hal.pciimportprint_pci_devices,print_pci_XROMs
-fromchipsec.hal.pciimportPCI_HDR_CLS_OFF,PCI_HDR_SUB_CLS_OFF,PCI_HDR_CMD_OFF
-
-# PCIe Devices and Configuration Registers
-
-
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2017, Google
-# 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.
-#
-
-"""
->>> chipsec_util reg read <reg_name> [<field_name>]
->>> chipsec_util reg read_field <reg_name> <field_name>
->>> chipsec_util reg write <reg_name> <value>
->>> chipsec_util reg write_field <reg_name> <field_name> <value>
->>> chipsec_util reg get_control <control_name>
->>> chipsec_util reg set_control <control_name> <value>
-
-Examples:
-
->>> chipsec_util reg read SMBUS_VID
->>> chipsec_util reg read HSFC FGO
->>> chipsec_util reg read_field HSFC FGO
->>> chipsec_util reg write SMBUS_VID 0x8088
->>> chipsec_util reg write_field BC BLE 0x1
->>> chipsec_util reg get_control BiosWriteEnable
->>> chipsec_util reg set_control BiosLockEnable 0x1
-"""
-
-fromchipsec.commandimportBaseCommand,toLoad
-fromargparseimportArgumentParser
-
-
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2019-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 smbios entrypoint
->>> chipsec_util smbios get [raw|decoded] [type]
-
-Examples:
-
->>> chipsec_util smbios entrypoint
->>> chipsec_util smbios get raw
-"""
-
-fromargparseimportArgumentParser
-fromchipsec.commandimportBaseCommand,toLoad
-fromchipsec.hal.smbiosimportSMBIOS
-fromchipsec.loggerimportprint_buffer_bytes
-fromchipsec.optionsimportOptions
-
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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 smbus read <device_addr> <start_offset> [size]
->>> chipsec_util smbus write <device_addr> <offset> <byte_val>
-
-Examples:
-
->>> chipsec_util smbus read 0xA0 0x0 0x100
-"""
-
-fromchipsec.commandimportBaseCommand,toLoad
-fromchipsec.loggerimportprint_buffer_bytes
-fromchipsec.hal.smbusimportSMBus
-fromargparseimportArgumentParser
-
-
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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 spd detect
->>> chipsec_util spd dump [device_addr]
->>> chipsec_util spd read <device_addr> <offset>
->>> chipsec_util spd write <device_addr> <offset> <byte_val>
-
-Examples:
-
->>> chipsec_util spd detect
->>> chipsec_util spd dump DIMM0
->>> chipsec_util spd dump 0xA0
->>> chipsec_util spd read DIMM2 0x0
->>> chipsec_util spd read 0xA0 0x0
->>> chipsec_util spd write 0xA0 0x0 0xAA
-"""
-
-fromchipsec.commandimportBaseCommand,toLoad
-fromchipsec.halimportsmbus,spd
-fromargparseimportArgumentParser
-
-
-
[docs]defspd_detect(self):
- self.logger.log("[CHIPSEC] Searching for DIMMs with SPD...")
- _dimms=self._spd.detect()
- if_dimmsisnotNone:
- self.logger.log("Detected the following SPD devices:")
- for_dimmin_dimms:
- self.logger.log("{}: 0x{:02X}".format(spd.SPD_DIMMS[_dimm],_dimm))
- else:
- self.logger.log("Unable to detect SPD devices.")
-
-
[docs]defspd_dump(self):
- ifself.devisnotNone:
- _dev=self.dev.upper()
- self.dev_addr=spd.SPD_DIMM_ADDRESSES[_dev]if_devinspd.SPD_DIMM_ADDRESSESelseint(self.dev,16)
- ifnotself._spd.isSPDPresent(self.dev_addr):
- self.logger.log("[CHIPSEC] SPD for DIMM 0x{:X} is not found".format(self.dev_addr))
- return
- self._spd.decode(self.dev_addr)
- else:
- _dimms=self._spd.detect()
- for_dimmin_dimms:
- self._spd.decode(_dimm)
-
-
[docs]defspd_read(self):
- _dev=self.dev.upper()
- self.dev_addr=spd.SPD_DIMM_ADDRESSES[_dev]if_devinspd.SPD_DIMM_ADDRESSESelseint(self.dev,16)
- ifnotself._spd.isSPDPresent(self.dev_addr):
- self.logger.log("[CHIPSEC] SPD for DIMM 0x{:X} is not found".format(self.dev_addr))
- return
-
- val=self._spd.read_byte(self.off,self.dev_addr)
- self.logger.log("[CHIPSEC] SPD read: offset 0x{:X} = 0x{:X}".format(self.off,val))
-
-
[docs]defspd_write(self):
- _dev=self.dev.upper()
- self.dev_addr=spd.SPD_DIMM_ADDRESSES[_dev]if_devinspd.SPD_DIMM_ADDRESSESelseint(self.dev,16)
- ifnotself._spd.isSPDPresent(self.dev_addr):
- self.logger.log("[CHIPSEC] SPD for DIMM 0x{:X} is not found".format(self.dev_addr))
- return
-
- self.logger.log("[CHIPSEC] SPD write: offset 0x{:X} = 0x{:X}".format(self.off,self.val))
- self._spd.write_byte(self.off,self.val,self.dev_addr)
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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 includes functionality for reading and writing the SPI flash. When an image file is created from reading the SPI flash, this image can be parsed to reveal sections, files, variables, etc.
-
-.. warning:: Particular care must be taken when using the SPI write and SPI erase functions. These could make your system unbootable.
-
-A basic forensic operation might be to dump the entire SPI flash to a file. This is accomplished as follows:
-
-``# python chipsec_util.py spi dump rom.bin``
-
-The file rom.bin will contain the full binary of the SPI flash. It can then be parsed using the decode util command.
-
->>> chipsec_util spi info|dump|read|write|erase|disable-wp [flash_address] [length] [file]
-
-Examples:
-
->>> chipsec_util spi info
->>> chipsec_util spi dump rom.bin
->>> chipsec_util spi read 0x700000 0x100000 bios.bin
->>> chipsec_util spi write 0x0 flash_descriptor.bin
->>> chipsec_util spi disable-wp
->>> chipsec_util spi sfdp
->>> chipsec_util spi jedec
->>> chipsec_util spi jedec decode
-"""
-
-importos
-fromchipsec.commandimportBaseCommand,toLoad
-fromchipsec.hal.spiimportSPI,BIOS
-fromchipsec.exceptionsimportSpiRuntimeError
-fromargparseimportArgumentParser
-
-
-# SPI Flash Controller
-
[docs]defspi_disable_wp(self):
- self.logger.log("[CHIPSEC] Trying to disable BIOS write protection..")
- #
- # This write protection only matters for BIOS range in SPI flash memory
- #
- ifself._spi.disable_BIOS_write_protection():
- self.logger.log_good("BIOS region write protection is disabled in SPI flash")
- else:
- self.logger.log_bad("Couldn't disable BIOS region write protection in SPI flash")
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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 spidesc <rom>
-
-Examples:
-
->>> chipsec_util spidesc spi.bin
-"""
-
-fromchipsec.commandimportBaseCommand,toLoad
-fromchipsec.fileimportread_file
-fromchipsec.hal.spi_descriptorimportparse_spi_flash_descriptor
-fromargparseimportArgumentParser
-
-
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2017, Google Inc
-# Copyright (c) 2010-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 tpm parse_log <file>
->>> chipsec_util tpm state <locality>
->>> chipsec_util tpm command <commandName> <locality> <command_parameters>
-
-locality: 0 | 1 | 2 | 3 | 4
-commands - parameters:
-pccrread - pcr number ( 0 - 23 )
-nvread - Index, Offset, Size
-startup - startup type ( 1 - 3 )
-continueselftest
-getcap - Capabilities Area, Size of Sub-capabilities, Sub-capabilities
-forceclear
-
-Examples:
-
->>> chipsec_util tpm parse_log binary_bios_measurements
->>> chipsec_util tpm state 0
->>> chipsec_util tpm command pcrread 0 17
->>> chipsec_util tpm command continueselftest 0
-"""
-
-fromchipsec.commandimportBaseCommand,toLoad
-fromchipsec.halimporttpm_eventlog
-fromchipsec.halimporttpm
-fromchipsec.exceptionsimportTpmRuntimeError
-fromchipsec.testcaseimportExitCode
-fromargparseimportArgumentParser
-
-
-
-# CHIPSEC: Platform Security Assessment Framework
-#
-# 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
-#
-
-"""
-Command-line utility providing access to Intel TXT (Trusted Execution Technology) registers
-
-Usage:
- >>> chipsec_util txt dump
- >>> chipsec_util txt state
-"""
-
-fromargparseimportArgumentParser
-fromchipsec.commandimportBaseCommand,toLoad
-fromchipsec.exceptionsimportHWAccessViolationError
-fromchipsec.testcaseimportExitCode
-importstruct
-
-
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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 ucode id|load|decode [ucode_update_file (in .PDB or .BIN format)] [cpu_id]
-
-Examples:
-
->>> chipsec_util ucode id
->>> chipsec_util ucode load ucode.bin 0
->>> chipsec_util ucode decode ucode.pdb
-"""
-
-fromchipsec.commandimportBaseCommand,toLoad
-fromchipsec.fileimportread_file
-fromchipsec.hal.ucodeimportdump_ucode_update_header
-fromargparseimportArgumentParser
-
-# ###################################################################
-#
-# Microcode patches
-#
-# ###################################################################
-
-
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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
-#
-
-
-"""
-The uefi command provides access to UEFI variables, both on the live system and in a SPI flash image file.
-
->>> chipsec_util uefi types
->>> chipsec_util uefi var-list
->>> chipsec_util uefi var-find <name>|<GUID>
->>> chipsec_util uefi var-read|var-write|var-delete <name> <GUID> <efi_variable_file>
->>> chipsec_util uefi decode <rom_file> [filetypes]
->>> chipsec_util uefi nvram[-auth] <rom_file> [fwtype]
->>> chipsec_util uefi keys <keyvar_file>
->>> chipsec_util uefi tables
->>> chipsec_util uefi s3bootscript [script_address]
->>> chipsec_util uefi assemble <GUID> freeform none|lzma|tiano <raw_file> <uefi_file>
->>> chipsec_util uefi insert_before|insert_after|replace|remove <GUID> <rom> <new_rom> <uefi_file>
-
-Examples:
-
->>> chipsec_util uefi types
->>> chipsec_util uefi var-list
->>> chipsec_util uefi var-find PK
->>> chipsec_util uefi var-read db D719B2CB-3D3A-4596-A3BC-DAD00E67656F db.bin
->>> chipsec_util uefi var-write db D719B2CB-3D3A-4596-A3BC-DAD00E67656F db.bin
->>> chipsec_util uefi var-delete db D719B2CB-3D3A-4596-A3BC-DAD00E67656F
->>> chipsec_util uefi decode uefi.rom
->>> chipsec_util uefi decode uefi.rom FV_MM
->>> chipsec_util uefi nvram uefi.rom vss_auth
->>> chipsec_util uefi keys db.bin
->>> chipsec_util uefi tables
->>> chipsec_util uefi s3bootscript
->>> chipsec_util uefi assemble AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE freeform lzma uefi.raw mydriver.efi
->>> chipsec_util uefi replace AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE bios.bin new_bios.bin mydriver.efi
-"""
-
-importos
-importuuid
-fromargparseimportArgumentParser
-
-fromchipsec.commandimportBaseCommand,toLoad
-fromchipsec.hal.uefi_commonimportEFI_STATUS_DICT,parse_efivar_file
-fromchipsec.fileimportwrite_file,read_file
-fromchipsec.hal.spi_uefiimportdecode_uefi_region,modify_uefi_region,compress_image,CMD_UEFI_FILE_REPLACE
-fromchipsec.hal.spi_uefiimportCMD_UEFI_FILE_INSERT_AFTER,CMD_UEFI_FILE_INSERT_BEFORE,CMD_UEFI_FILE_REMOVE
-fromchipsec.hal.uefiimportUEFI,decode_EFI_variables,get_attr_string,identify_EFI_NVRAM
-fromchipsec.hal.uefiimportSECURE_BOOT_KEY_VARIABLES,parse_script,parse_EFI_variables
-fromchipsec.hal.uefi_fvimportget_guid_bin,assemble_uefi_file,assemble_uefi_section,assemble_uefi_raw
-fromchipsec.hal.uefi_fvimportFILE_TYPE_NAMES
-fromchipsec.hal.uefi_platformimportfw_types
-
-
-# Unified Extensible Firmware Interface (UEFI)
-
[docs]defkeys(self):
- ifnotos.path.exists(self.filename):
- self.logger.log_error("Could not find file '{}'".format(self.filename))
- return
- self.logger.log("<keyvar_file> should contain one of the following EFI variables\n[ %s ]"%(" | ".join(["%s"%varforvarinSECURE_BOOT_KEY_VARIABLES])))
- self.logger.log("[CHIPSEC] Parsing EFI variable from '{}'..".format(self.filename))
- parse_efivar_file(self.filename)
-
-
[docs]deftables(self):
- self.logger.log("[CHIPSEC] Searching memory for and dumping EFI tables (this may take a minute)..\n")
- self._uefi.dump_EFI_tables()
-
-
[docs]defs3bootscript(self):
- self.logger.log("[CHIPSEC] Searching for and parsing S3 resume bootscripts..")
- ifself.bootscript_paisnotNone:
- self.logger.log('[*] Reading S3 boot-script from memory at 0x{:016X}..'.format(self.bootscript_pa))
- script_all=self.cs.mem.read_physical_mem(self.bootscript_pa,0x100000)
- self.logger.log('[*] Decoding S3 boot-script opcodes..')
- script_entries=parse_script(script_all,True)
- else:
- (bootscript_PAs,parsed_scripts)=self._uefi.get_s3_bootscript(True)
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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
-#
-
-
-"""
-The vmem command provides direct access to read and write virtual memory.
-
->>> chipsec_util vmem <op> <physical_address> <length> [value|buffer_file]
->>>
->>> <physical_address> : 64-bit physical address
->>> <op> : read|readval|write|writeval|allocate|pagedump|search|getphys
->>> <length> : byte|word|dword or length of the buffer from <buffer_file>
->>> <value> : byte, word or dword value to be written to memory at <physical_address>
->>> <buffer_file> : file with the contents to be written to memory at <physical_address>
-
-Examples:
-
->>> chipsec_util vmem <op> <virtual_address> <length> [value|file]
->>> chipsec_util vmem readval 0xFED40000 dword
->>> chipsec_util vmem read 0x41E 0x20 buffer.bin
->>> chipsec_util vmem writeval 0xA0000 dword 0x9090CCCC
->>> chipsec_util vmem write 0x100000000 0x1000 buffer.bin
->>> chipsec_util vmem write 0x100000000 0x10 000102030405060708090A0B0C0D0E0F
->>> chipsec_util vmem allocate 0x1000
->>> chipsec_util vmem search 0xF0000 0x10000 _SM_
->>> chipsec_util vmem getphys 0xFED00000
-"""
-
-importos
-importchipsec_util
-
-fromchipsec.commandimportBaseCommand,toLoad
-fromchipsec.halimportvirtmem
-fromchipsec.definesimportbytestostring
-fromchipsec.loggerimportprint_buffer_bytes
-fromchipsec.fileimportwrite_file,read_file
-fromargparseimportArgumentParser
-
-
-# Virtual Memory
-
-# CHIPSEC: Platform Security Assessment Framework
-# Copyright (c) 2010-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 vmm hypercall <rax> <rbx> <rcx> <rdx> <rdi> <rsi> [r8] [r9] [r10] [r11]
->>> chipsec_util vmm hypercall <eax> <ebx> <ecx> <edx> <edi> <esi>
->>> chipsec_util vmm pt|ept <ept_pointer>
->>> chipsec_util vmm virtio [<bus>:<device>.<function>]
-
-Examples:
-
->>> chipsec_util vmm hypercall 32 0 0 0 0 0
->>> chipsec_util vmm pt 0x524B01E
->>> chipsec_util vmm virtio
->>> chipsec_util vmm virtio 0:6.0
-"""
-
-importre
-
-fromchipsec.commandimportBaseCommand,toLoad
-fromchipsec.hal.vmmimportVMM,get_virtio_devices,VirtIO_Device
-fromchipsec.hal.pciimportprint_pci_devices
-fromchipsec.exceptionsimportVMMRuntimeError
-fromargparseimportArgumentParser
-
-
-
-
-
-
\ No newline at end of file
diff --git a/_sources/index.rst.txt b/_sources/index.rst.txt
index 61d721be..0a002284 100644
--- a/_sources/index.rst.txt
+++ b/_sources/index.rst.txt
@@ -1,9 +1,9 @@
-.. CHIPSEC 1.13.3 documentation file, created by
+.. CHIPSEC 1.13.4 documentation file, created by
sphinx-quickstart on Wed Mar 25 13:24:44 2015.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
-CHIPSEC 1.13.3
+CHIPSEC 1.13.4
==============
CHIPSEC is a framework for analyzing platform level security of
diff --git a/_sources/modules/chipsec.options.rst.txt b/_sources/modules/chipsec.options.rst.txt
deleted file mode 100644
index 1a164f74..00000000
--- a/_sources/modules/chipsec.options.rst.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-chipsec.options module
-======================
-
-.. automodule:: chipsec.options
- :members:
- :undoc-members:
- :show-inheritance:
diff --git a/contribution/code-style-python.html b/contribution/code-style-python.html
index 901a689e..85fdf0bc 100644
--- a/contribution/code-style-python.html
+++ b/contribution/code-style-python.html
@@ -620,7 +620,7 @@
CHIPSEC is a framework for analyzing platform level security of
hardware, devices, system firmware, low-level protection mechanisms, and
the configuration of various platform components.