Commit Graph

1875 Commits

Author SHA1 Message Date
Sara Batllori 474bbfd0d9 Change default log level to INFO
Signed-off-by: Sara Batllori <sara.batllori@intel.com>
2023-06-20 16:37:11 -07:00
Nicolas Iooss 6d52c2c54f Add type hints to helper.linuxnative.cpuid
With these annotations, mypy no longer report any issues in strict mode:

    $ mypy --strict chipsec/helper/linuxnative/cpuid.py
    Success: no issues found in 1 source file

Signed-off-by: Nicolas Iooss <nicolas.iooss_git@polytechnique.org>
2023-06-20 16:37:01 -07:00
Nicolas Iooss f0ebbe01cc Simplify CPUID code mapping in linuxnative helper
Make the machine code `bytes` instead of `list`. This makes it no longer
necessary to cast it to `c_ubyte * size` before using it.

While at it, add `mmap.MAP_PRIVATE` flag to the mapping, as it is not
needed to create a `MAP_SHARED` mapping for the code (which is the
default flag).

Signed-off-by: Nicolas Iooss <nicolas.iooss_git@polytechnique.org>
2023-06-20 16:37:01 -07:00
Nicolas Iooss fb80548746 Remove print_function import
Now that chipsec is no longer compatible with Python2, this import is no
longer useful.

Signed-off-by: Nicolas Iooss <nicolas.iooss_git@polytechnique.org>
2023-06-20 16:37:01 -07:00
Nicolas Iooss 14c5f7c314 Directly import chipsec.helper.linuxnative.cpuid in linuxnative
There is no point in doing a lazy-import with
`chipsec.helper.linuxnative.cpuid`, as the `cpuid` function is almost
always called when starting chipsec, to display the banner.

Signed-off-by: Nicolas Iooss <nicolas.iooss_git@polytechnique.org>
2023-06-20 16:37:01 -07:00
Nicolas Iooss 470820d464 Use c_void_p instead of c_voidp
`ctypes.c_voidp` was a bug which is kept in ctypes for backward
compatibility. This is documented in
https://github.com/python/cpython/blob/3.10/Lib/ctypes/__init__.py#L246
:

    c_voidp = c_void_p # backwards compatibility (to a bug)

Replace the use of `c_voidp` with `c_void_p`.

Signed-off-by: Nicolas Iooss <nicolas.iooss_git@polytechnique.org>
2023-06-20 16:37:01 -07:00
Dan Scott 2872f2fd90 Add typehints and fstrings to interrupts_cmd.py
Signed-off-by: Dan Scott <dan.scott@intel.com>
2023-06-20 16:36:48 -07:00
Nicolas Iooss 09f421639e Rework legacy PCI helper
When using chipsec.chipset Python module from an unprivileged user, the
Python interpreter crashes with a segmentation fault on an `outl`
instruction. This is because `iopl(3)` failed and the "legacy PCI"
implementation tried to write a value to an I/O port without being
allowed to.

Fix this by checking the return value of `iopl`.

While at it, enable using `error` in the C library, to properly report
the `EPERM` error.

While working on this code, it appeared that:

- `self.addr` was written twice in `PORTS`' constructor: once for the
  `inl` implementation and another one for `outl`.
- Everytime `PORTS` or `LEGACY_PCI` objects were created, some memory
  was allocated (with `mmap.mmap`) to run the helpers and this memory
  was never freed.
- The global variables `IN_PORT` and `OUT_PORT` were defined as lists
  but always used as bytes.

Fix these issues by spliting `self.addr` into two variables, by
introducing a class property which re-use previous `PORTS` instances
(making this class a singleton) and by making `IN_PORT` and `OUT_PORT`
directly `bytes`.

While at it, change the names to the usual camel case convention
(`PORTS` -> `Ports` and `LEGACY_PCI` -> `LegacyPci`) and add type hints.

Signed-off-by: Nicolas Iooss <nicolas.iooss_git@polytechnique.org>
2023-06-14 16:38:57 -07:00
Frinzell, Aaron 31db8c3bab Consistent variable return types in uefi_platform.py
Signed-off-by: Frinzell, Aaron <aaron.frinzell@intel.com>
2023-06-14 16:38:45 -07:00
Dan Scott daf7d63d9f Add typehints and fstrings to decode_cmd.py
Signed-off-by: Dan Scott <dan.scott@intel.com>
2023-06-14 16:38:34 -07:00
Dan Scott 1841d2f1a2 Add typehints and fstrings to io_cmd.py
Signed-off-by: Dan Scott <dan.scott@intel.com>
2023-06-14 16:38:12 -07:00
Dan Scott d831476c65 Add typehints and fstrings to iommu_cmd.py
Signed-off-by: Dan Scott <dan.scott@intel.com>
2023-06-14 16:38:05 -07:00
Dan Scott 01574b182b Add typehints and fstrings to mem_cmd.py
Signed-off-by: Dan Scott <dan.scott@intel.com>
2023-06-14 16:37:51 -07:00
Dan Scott 2e05fde8e4 Add typehints and fstrings to mmcfg_base_cmd.py
Signed-off-by: Dan Scott <dan.scott@intel.com>
2023-06-14 16:37:38 -07:00
Dan Scott c0adee5d6e Add typehints and fstrings to mmcfg_cmd.py
Signed-off-by: Dan Scott <dan.scott@intel.com>
2023-06-14 16:37:27 -07:00
Frinzell, Aaron fa4067e5d3 Update core developers list
Signed-off-by: Frinzell, Aaron <aaron.frinzell@intel.com>
2023-06-13 16:40:49 -07:00
Nicolas Iooss 54f7348d6a Intel TXT: add field definitions from project Slim Bootloader
Project Slim Bootloader
(https://github.com/slimbootloader/slimbootloader) defines the content
of the ACM Policy Status at `0xFED30000+0x378` in
https://github.com/slimbootloader/slimbootloader/blob/c9d70e74dcfe5308ca1cf31279ee2a3e4b9bb7bb/Silicon/CommonSocPkg/Library/BootGuardLibCBnT/BootGuardTpmEventLogLib.c#L442-L470

    typedef union {
      struct {
        UINT64 KmId               : 4;      // 0-3   Key Manifest ID used for verified Key Manifest
        UINT64 MeasuredBoot       : 1;      // 4     perform measured boot
    ...
        UINT64 TpmStartupLocality : 1;      // 36    TPM startup locality.
        UINT64 Reserved           :27;      // 37-63
      } Bits;
      UINT64 Data;
    } ACM_BIOS_POLICY;

A previous version of this structure (before Pull Request
https://github.com/slimbootloader/slimbootloader/pull/1859 , commit
https://github.com/slimbootloader/slimbootloader/commit/ba9da25442b1d4fefd2675f7e21382a55b05684a)
also defined bits `KmArbEn` and `BpmArbEn`.

Signed-off-by: Nicolas Iooss <nicolas.iooss_git@polytechnique.org>
2023-06-13 16:40:24 -07:00
Dan Scott fda5180304 Add typehints and fstrings to desc_cmd.py
Signed-off-by: Dan Scott <dan.scott@intel.com>
2023-06-13 16:40:07 -07:00
Dan Scott 5c5f334a76 Add typehints and fstrings to deltas_cmd.py
Signed-off-by: Dan Scott <dan.scott@intel.com>
2023-06-13 16:39:49 -07:00
Dan Scott 5696bd9f74 Add typehints and fstrings to cpu_cmd.py
Signed-off-by: Dan Scott <dan.scott@intel.com>
2023-06-13 16:39:13 -07:00
Dan Scott 704685a477 Add typehints and fstrings to cpu_cmd.py
Signed-off-by: Dan Scott <dan.scott@intel.com>
2023-06-13 16:39:13 -07:00
Dan Scott 2e8becedc0 Add typehints and fstrings to cpu_cmd.py
Signed-off-by: Dan Scott <dan.scott@intel.com>
2023-06-13 16:39:13 -07:00
Frinzell, Aaron 22314780a3 Add Python 3.12 PEP changes to Code Style document
Signed-off-by: Frinzell, Aaron <aaron.frinzell@intel.com>
2023-06-12 16:53:28 -07:00
Nicolas Iooss 0de47d572a Add Alpine 3.18 and Debian 12 to Github Action test matrix
Alpine 3.18 was released on 2023-05-19 and Debian 12 on 2023-06-10.

Signed-off-by: Nicolas Iooss <nicolas.iooss_git@polytechnique.org>
2023-06-12 16:53:06 -07:00
Dan Scott 17fee6c79b Add 600 Series PCH Device IDs to config
Signed-off-by: Dan Scott <dan.scott@intel.com>
2023-06-12 16:52:45 -07:00
Nicolas Iooss 98925eac10 Read the AMD LPC revision ID using the correct BDF address
On AMD, the "PCH" is the LPC device on PCI 0:14.3. According to "PPR for
AMD Family 17h Model 18h B1. 55570-B1 Rev 3.16 - Apr 14, 2021."
available on
https://www.amd.com/en/support/tech-docs/processor-programming-reference-ppr-for-amd-family-17h-model-18h-revision-b1
the low byte at D14F3x008 (bus 0 device 14 function 3 offset 8) is the
RevisionID of this device.

Using 0:1F.0 to read the RID in `Chipset.detect_platform` is likely to
be a bug from commit 2691f50bae ("Detect PCH based on platform vendor
ID"), which introduced AMD support in this function. Fix this by using
`bus, dev, fun` to read `pch_rid`.

Signed-off-by: Nicolas Iooss <nicolas.iooss_git@polytechnique.org>
2023-06-12 16:43:48 -07:00
Sara Batllori 5ccd4b817e Add -nl switch to disable autologging
Signed-off-by: Sara Batllori <sara.batllori@intel.com>
2023-06-12 16:42:28 -07:00
Nicolas Iooss b52eb902c5 Remove global variable chipsec.helper.oshelper.avail_helper
This global variable is no longer used after commit 4b9ab99839
("Change the way helper loading is done"). Update the documentation too.

Signed-off-by: Nicolas Iooss <nicolas.iooss_git@polytechnique.org>
2023-06-07 16:36:54 -07:00
Nicolas Iooss 36ca6fa5a7 Make defines.is_printable support bytes
`uefi_search.py` calls `is_printable` with bytes, in:

    m = re.compile(bytes(rule['regexp'], 'utf-8')).search(efi.Image)
    if m:
        match_result |= MATCH_REGEXP
        _str = m.group(0)
        hexver = binascii.hexlify(_str)
        printver = f" ('{_str}')" if defines.is_printable(_str) else ''

... because `_str` has actually type `bytes`, not `str`.

When `is_printable` is called with bytes, it always return `False`,
because in

    set(seq).issubset(set(string.printable))

`set(seq)` is a set of integers and `set(string.printable)` is a set of
strings.

Fix this by always converting the parameter to string, using
`bytestostring`. This is not the most efficient way of doing this (a
more efficient would be `set(seq).issubset(set(string.printable.encode()))`
with some caching of the second set) but it is simple and makes caller
less likely to use the function in an unsupported way.

Signed-off-by: Nicolas Iooss <nicolas.iooss_git@polytechnique.org>
2023-06-05 16:45:19 -07:00
Nicolas Iooss c2bcf585ec Fix Linux native helper MMIO read/write
Reading 64-bit MMIO registers does not work with Linux native helper.
For example:

    $ ./chipsec_util.py --helper linuxnativehelper txt state
    ...
    TXT Public Key Hash: 9c78f0d8000000002f47761c00000000164a66a90000000092e3144f00000000

This value comes from four 64-bit MMIO registers (`TXT_PUBLIC_KEY_0` to
`TXT_PUBLIC_KEY_3`). This is caused by `LinuxNativeHelper.read_mmio_reg`
assuming the size cannot be larger than 4. And it also assumes that the
physical address is always aligned on a 4-byte boundary.

Reading a value as a "32-bit integer" can be important for MMIO
registers, so do not change this case, when the physical address is
aligned. In practice:

- If `size == 1`, the result can be directly read from the mapping.
- Otherwise, if the address is aligned,
  `region_mv.cast(defines.SIZE2FORMAT[size])` can be used to trigger an
  atomic read of the requested size.
- In the unaligned case, the bytes are read from the memory view,
  possibly one by one, and `defines.unpack1` is used to glue them back
  to an integer.

Implement a similar logic in `write_mmio_reg` too. While at it, as the
`return 0` did not make much sense in this function, remove it.

With this commit:

    $ ./chipsec_util.py --helper linuxnativehelper txt state
    ...
    TXT Public Key Hash: 9c78f0d853de854a2f47761c72b86a11164a66a984c1aad792e3144fb71c2d11

Signed-off-by: Nicolas Iooss <nicolas.iooss_git@polytechnique.org>
2023-06-05 16:44:00 -07:00
Nicolas Iooss e8d41ab9ee Replace binascii.hexlify with bytes.hex
Python 3.5 introduced `bytes.hex` to represent bytes in hexadecimal:
https://docs.python.org/3.5/library/stdtypes.html#bytes.hex

This function directly returns a string, contrary to `binascii.hexlify`
which returns bytes. Using `binascii.hexlify` without transforming the
output to string actually produced buggy output. For example:

    $ ./chipsec_util.py spidesc spi_rom.bin
    ...
    + 0x0000 Reserved : 0xb'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'

This `b'` is not desired. Using `bytes.hex` fixes this issue and makes
the code simpler.

Signed-off-by: Nicolas Iooss <nicolas.iooss_git@polytechnique.org>
2023-06-05 16:43:15 -07:00
Nicolas Iooss 1d4e2c2482 Fix Chipset.set_control call to write_register_field
`Chipset.set_control` calls:

    self.write_register_field(reg, field, control_value, cpu_thread)

But `write_register_field` is defined as:

    def write_register_field(self, reg_name, field_name, field_value, preserve_field_position=False, cpu_thread=0):

So variable `cpu_thread` is given to parameter `preserve_field_position`
instead of parameter `cpu_thread`.

Fix this by using `cpu_thread=cpu_thread` syntax in the call.

This bug was found while adding type hints to `chipset`. Mypy reported:

    Argument 4 to "write_register_field" of "Chipset" has incompatible type "int"; expected "bool"

Signed-off-by: Nicolas Iooss <nicolas.iooss_git@polytechnique.org>
2023-06-05 16:42:39 -07:00
Nathaniel Mitchell 099bbdbdfa Add basic init to Chipset object if only helper is wanted
Signed-off-by: Nathaniel Mitchell <nathaniel.p.mitchell@intel.com>
2023-06-05 16:41:39 -07:00
Nathaniel Mitchell 4b38d41a29 Move helper.getcwd() from *helper to oshelper
Signed-off-by: Nathaniel Mitchell <nathaniel.p.mitchell@intel.com>
2023-06-05 16:41:07 -07:00
Nicolas Iooss 7e19c7c89c Remove hex_to_text from logger
This function was never used. Moreover it does not work with numbers
with an odd number of hexdigits because `binascii.unhexlify(f'{value:x}')`
fails with:

    >>> hex_to_text(1)
    binascii.Error: Odd-length string

Signed-off-by: Nicolas Iooss <nicolas.iooss_git@polytechnique.org>
2023-06-05 16:37:05 -07:00
Frinzell, Aaron 1710b3e37c Banner.py use cs.cpuid value
Signed-off-by: Frinzell, Aaron <aaron.frinzell@intel.com>
2023-06-05 16:36:35 -07:00
Nicolas Iooss 1fe35eaff7 Add Python 3.11 to Github Action workflow
Python 3.11 was released in October 2022:
https://www.python.org/downloads/release/python-3110/

Signed-off-by: Nicolas Iooss <nicolas.iooss_git@polytechnique.org>
2023-06-02 16:44:04 -07:00
Nicolas Iooss a01d537a75 Make OsHelper.get_available_helpers return a sorted list
`OsHelper.get_available_helpers` is returning a list of helper names in
the order they are stored in the dict `self.avail_helpers`. This order
seems to come from the order in which `os.listdir(helper_dir)` reads the
content of the directory.

To make this order more predictible and meaningful, sort the list in
`get_available_helpers`. This function was only called when generating
the documentation ofi option `--helper` and this makes it more
reproducible too.

Signed-off-by: Nicolas Iooss <nicolas.iooss_git@polytechnique.org>
2023-06-02 08:48:34 -07:00
Jason Zhou 1b1864adbf remove the windows build tool version dependency
Signed-off-by: Jason Zhou <jun2.zhou@intel.com>
2023-06-02 08:47:29 -07:00
Nicolas Iooss 13e98fabc6 Format bytes with .hex() instead of :8X
Using `{buf:8X}` does not work in `LinuxNativeHelper.write_msr`: this
raises an expection

    TypeError: unsupported format string passed to bytes.__format__

Use `{buf.hex()}` instead to format the bytes in the error message.

Signed-off-by: Nicolas Iooss <nicolas.iooss_git@polytechnique.org>
2023-06-02 08:45:39 -07:00
Nicolas Iooss a61dbc8d2b Make mocked function read_phys_mem return bytes
In tests, `read_phys_mem` could return strings instead of bytes, which
prevents detecting issues with `chipsec_util.py gdt` and
`chipsec_util.py idt`.

Signed-off-by: Nicolas Iooss <nicolas.iooss_git@polytechnique.org>
2023-05-31 16:39:35 -07:00
Nicolas Iooss 9be66dadbd Replace print_buffer(bytestostring(data)) with print_buffer_bytes
`print_buffer_bytes` can directly handle bytes, instead of converting
them to a string.

While at it, replace buggy calls to `print_buffer(buffer)` (when
`buffer` uses type `bytes`) with `print_buffer_bytes(buffer)`.
This fixes `./chipsec_util.py idt 0`. Before it failed with:

    [CHIPSEC] Dumping IDT of 8 CPU threads
    [cpu0] Physical Address: 0x000000036639E000
    [cpu0] # of entries    : 256
    [cpu0] Contents (4 entries):
    Traceback (most recent call last):
      File "./chipsec_util.py", line 210, in <module>
        sys.exit(main())
      File "./chipsec_util.py", line 205, in main
        return chipsecMain.main()
      File "./chipsec_util.py", line 190, in main
        comm.run()
      File "chipsec/utilcmd/desc_cmd.py", line 84, in run
        self.cs.msr.IDT_all(4)
      File "chipsec/hal/msr.py", line 166, in IDT_all
        self.IDT(tid, num_entries)
      File "chipsec/hal/msr.py", line 158, in IDT
        return self.dump_Descriptor_Table(cpu_thread_id, DESCRIPTOR_TABLE_CODE_IDTR, num_entries)
      File "chipsec/hal/msr.py", line 144, in dump_Descriptor_Table
        print_buffer(dt)
      File "chipsec/logger.py", line 493, in print_buffer
        prt_str = bytes2string(arr, length)
      File "chipsec/logger.py", line 466, in bytes2string
        num_string += [f'{ord(c):02X} ']
    TypeError: ord() expected string of length 1, but int found

There was another bug in `hal/msr.py` where `ord(dt[...])` was used
instead of `dt`.

Signed-off-by: Nicolas Iooss <nicolas.iooss_git@polytechnique.org>
2023-05-31 16:39:35 -07:00
Nicolas Iooss 7806ebd04c Make EC, SMBus and SPD use bytes instead of list of characters
Using a list of unicode characters instead of bytes is strange in Python
3. Replace these lists with bytes, which is the usual type to hold
binary data.

Signed-off-by: Nicolas Iooss <nicolas.iooss_git@polytechnique.org>
2023-05-31 16:39:20 -07:00
Nicolas Iooss a8fb150415 Fix SPI write when data size is not a multiple of 4
In `SPI.write_spi`, When `len(buf) % 4 != 0`, a dword value to be
written is computed with `ord(buf[...])`. This does not work, as in
Python 3, `buf[...]` directly gives an integer.

Fix this issue by removing the call to `ord`.

Fixes: https://github.com/chipsec/chipsec/issues/1775
Signed-off-by: Nicolas Iooss <nicolas.iooss_git@polytechnique.org>
2023-05-31 16:39:08 -07:00
Nicolas Iooss cebe2ff1e9 Import UnimplementedAPIError from chipsec.exceptions
`oshelper.UnimplementedAPIError` is actually imported from
`chipsec.exceptions`. Importing it directly fixes warnings reported by
Mypy such as:

    chipsec/hal/spi.py:201: error: Module has no attribute "UnimplementedAPIError"

Signed-off-by: Nicolas Iooss <nicolas.iooss_git@polytechnique.org>
2023-05-31 16:38:51 -07:00
Nathaniel Mitchell 00ba41226e Update to 1.11.0
Signed-off-by: Nathaniel Mitchell <nathaniel.p.mitchell@intel.com>
1.11.0
2023-05-31 09:40:42 -07:00
Frinzell, Aaron 5484e6e7e4 Fix search_efi_tree() return in spi_uefi.py
Signed-off-by: Frinzell, Aaron <aaron.frinzell@intel.com>
2023-05-31 09:29:04 -07:00
Nicolas Iooss 72121ae8a2 Make chipsec.init() resilient to platform with unknown VID/DID
If the vendor ID or the device ID returned by `detect_platform()` is not
known in `chipset_dictionary`, accessing
`self.chipset_dictionary[vid][did]` raises a `KeyError` exception. To
prevent this, use the variables `vid_found` and `did_found` before
accessing `self.chipset_dictionary[vid][did]`.

Signed-off-by: Nicolas Iooss <nicolas.iooss_git@polytechnique.org>
2023-05-30 16:38:44 -07:00
Nicolas Iooss 53fd93f946 Fix spidesc table of Master Read/Write Access to Flash Regions
Currently, `chipsec_util.py spidesc spi_rom.bin` displays:

    Master Read/Write Access to Flash Regions
    --------------------------------------------------------
     Region                 | CPU      | ME
    --------------------------------------------------------
    f{r:-2d} {spi.SPI_REGION_NAMES[r]:20s} |          |

The `f` was not positioned correctly in the formatted string.

Signed-off-by: Nicolas Iooss <nicolas.iooss_git@polytechnique.org>
2023-05-30 16:38:18 -07:00
Frinzell, Aaron 2492224be0 Fix circular dependency with get_datetime_str()
Signed-off-by: Frinzell, Aaron <aaron.frinzell@intel.com>
2023-05-30 16:37:39 -07:00