diff --git a/Makefile b/Makefile deleted file mode 100644 index d5f9900..0000000 --- a/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line, and also -# from the environment for the first two. -SPHINXOPTS ?= -SPHINXBUILD ?= sphinx-build -SOURCEDIR = docs/source -BUILDDIR = build - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -livehtml: - sphinx-autobuild "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -.PHONY: help livehtml Makefile - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/README.md b/README.md index 5323d82..0dc6cff 100644 --- a/README.md +++ b/README.md @@ -110,18 +110,10 @@ to generate detailed code documentation automatically. To generate the documentation run the following: ```bash -(venv) make html -python -m http.server 8000 +(venv) mkdocs serve ``` -For live preview run: - -```bash -(venv) make livehtml -``` - -Open the web browser and type `localhost:8000` as address. Or alternatively -open `build/html/index.html` file in the web browser directly. +Open the web browser and type `localhost:8000` as address. ## Checking Python style diff --git a/docs/coreboot.md b/docs/coreboot.md new file mode 100644 index 0000000..a945365 --- /dev/null +++ b/docs/coreboot.md @@ -0,0 +1,5 @@ +::: openness_score.coreboot + handler: python + options: + filters: [] + docstring_style: sphinx diff --git a/docs/source/design.rst b/docs/design.md similarity index 67% rename from docs/source/design.rst rename to docs/design.md index 7c8498d..319863a 100644 --- a/docs/source/design.rst +++ b/docs/design.md @@ -1,11 +1,8 @@ -Dasharo Openness Score design -============================= +# Dasharo Openness Score design Dasharo Openness Score is designed following a few patterns and design rules. - -Dasharo Openness Score general rules ------------------------------------- +## Dasharo Openness Score general rules 1. The utility should not leave any intermediate files during the firmware image processing. @@ -23,29 +20,28 @@ Dasharo Openness Score general rules 3. The utility must be sa precise as possible to avoid falsified results. -Dasharo Openness Score module design rules ------------------------------------------- +## Dasharo Openness Score module design rules Each class representing a firmware image (or its integral part): 1. Must calculate the 4 basic metrics (empty, data, closed-source and open-source) on the class instance creation. -2. Should have a string method ``__str__`` which returns a set of 4 basic +2. Should have a string method `__str__` which returns a set of 4 basic metrics and general attributes of the entity -3. Should have a length method ``__len__`` which returns the size of the +3. Should have a length method `__len__` which returns the size of the firmware image (or its integral part) 4. Must contain attributes for the basic metrics using the following names: - ``self.open_code_size``, ``self.closed_code_size``, ``self.data_size`` and - ``self.empty_size`` -5. Must implement ``export_markdown`` method that will produce a markdown + `self.open_code_size`, `self.closed_code_size`, `self.data_size` and + `self.empty_size` +5. Must implement `export_markdown` method that will produce a markdown report of the firmware image (or its integral part) statistics -6. Must implement ``_calculate_metrics`` method which will perform the image +6. Must implement `_calculate_metrics` method which will perform the image component classification and do the calculations 7. Should implement a parse method which will perform the extraction of the image components and its attributes -8. Must call the parse method and ``_calculate_metrics`` inside the class' - ``__init__`` method -9. Must implement ``export_charts`` method to generate pie charts (only for +8. Must call the parse method and `_calculate_metrics` inside the class' + `__init__` method +9. Must implement `export_charts` method to generate pie charts (only for classes representing the whole firmware image) 10. Must assume a component as closed-source if unable to classify to any category. diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..853523e --- /dev/null +++ b/docs/index.md @@ -0,0 +1,32 @@ +# Dasharo Openness Score + +## What is Dasharo Openness Score + +Have you ever wondered how open is your open-source firmware? How much +closed-source and binary blobs is still there? Dasharo Openness Score utility +answers those questions. + +Dasharo Openness is a report showing the open-source code to closed-source +code ratio in the Dasharo firmware images. The results are also presented as a +pie chart for better visual representation of the firmware image components +and their share percentage. + +Dasharo Openness Score utility is capable of parsing Dasharo coreboot-based +images as well as vendor UEFI images. Thanks to that one can easily compare +how many bytes of the firmware have been liberated as well as by how much the +Trusted Computing Base (TCB) has been reduced. + +Dasharo Openness Score utility not only support Dasharo coreboot-based images, +but also many more coreboot distributions like heads. + +## How does it work? + +The utility leverages various tools like [coreboot's cbfstool][cbfstool] or +[LongSoft's UEFIExtract][uefiextract] to decompose and parse the firmware +images. The output from the utilities is used to detect the image type and then +to calculate the openness metrics. + +For more details please refer to the [methodology document](./methodology.md) + +[cbfstool]: https://github.com/coreboot/coreboot/tree/master/util/cbfstool +[uefiextract]: https://github.com/LongSoft/UEFITool diff --git a/docs/source/methodology.rst b/docs/methodology.md similarity index 55% rename from docs/source/methodology.rst rename to docs/methodology.md index f029172..1f4ed26 100644 --- a/docs/source/methodology.rst +++ b/docs/methodology.md @@ -1,12 +1,10 @@ -Dasharo Openness Score methodology -================================== +# Dasharo Openness Score methodology Dasharo Openness Score calculation methodology is different for UEFI images and coreboot-based images mainly due to their different structure, but also for calculation simplicity. -Calculating Dasharo Openness Score for UEFI images --------------------------------------------------- +## Calculating Dasharo Openness Score for UEFI images Axiom: UEFI images are always assumed to be vendor firmware images, thus the methodology assumes no open-source code. @@ -14,34 +12,33 @@ methodology assumes no open-source code. The utility makes decisions based on the report produced by UEFIExtract. The calculation flow looks as follows: -1. Look for the entries of type ``Region`` and save their properties for later. +1. Look for the entries of type `Region` and save their properties for later. Also separate the BIOS Region which will be used later. 2. Start classifying entries: * Take all non-BIOS regions and classify them as either closed-source group or data regions, based on known region types. For unknown region types, classify it as closed-source region. - * Take all entries in the BIOS region and extract UEFI Firmware Volumes - from them. Create new :class:`uefi.UEFIVolume` instances, which trigger - the UEFI Volume calculations described in section `Calculating metrics - for UEFI Firmware Volumes`_. Save all instances in the array for future - calculations. + * Take all entries in the BIOS region and extract UEFI Firmware Volumes from + them. Create new [uefi.UEFIVolume][uefivolume] instances, which trigger the + UEFI Volume calculations described in section + [Calculating metrics for UEFI Firmware Volumes](#calculating-metrics-for-uefi-firmware-volumes). + Save all instances in the array for future calculations. * Take all empty paddings between UEFI Firmware Volumes in BIOS region and between regions and add them to the empty region group. * Take all non-empty paddings between UEFI Firmware Volumes in BIOS region and between regions and add them to the data region group. 3. Sum up the size of all region groups: empty, data and closed-source. -4. Sum up the size of all groups from all :class:`uefi.UEFIVolume` instances - saved in the array previously: empty, data and closed-source. +4. Sum up the size of all groups from all `UEFIVolume` instances saved in the + array previously: empty, data and closed-source. 5. Check if the sums from point 3 and 4 give the total size of the image. If yes, do nothing. If not add the difference to the data group and print an error. -6. Export the data to markdown and pie charts using the - :meth:`uefi.UEFIVolume.export_markdown`. +6. Export the data to markdown and pie charts using + [UEFIVolume.export_markdown][uv_export_markdown]. -Calculating metrics for UEFI Firmware Volumes -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +### Calculating metrics for UEFI Firmware Volumes Axiom: Some UEFI Firmware Volumes may cotnain nested volumes that are compressed. Compressed entries i nthe UEFIExtract report do not have the base @@ -49,13 +46,13 @@ address of the components, just uncompressed size. To simplify the calculations and reliably present the data on charts, compressed UEFI Firmware Volumes are classified as closed-source as a whole. -Whenever a new instance of :class:`uefi.UEFIVolume` is created, the utility +Whenever a new instance of [UEFIVolume][uefivolume] is created, the utility performs the following steps: 1. Parse the report entries and extract only those belonging to given volume. -2. Create a new instance of :class:`uefi.UEFIVolume` for each nested - uncompressed UEFI Firmware Volume (FFSv2). This triggers the whole UEFI - Firmware Volume calculation procedure recursively. +2. Create a new instance of `UEFIVolume` for each nested uncompressed UEFI + Firmware Volume (FFSv2). This triggers the whole UEFI Firmware Volume + calculation procedure recursively. 3. Start classifying entries: * Take all empty paddings and volume free space inside the current UEFI @@ -68,13 +65,13 @@ performs the following steps: 4. Sum up the size of all groups classified up to now: empty, data and closed-source (there is currently no closed-source classified yet, so it will be 0). -5. Sum up the size of all groups from all nested :class:`uefi.UEFIVolume` - instances: empty, data and closed-source. +5. Sum up the size of all groups from all nested `UEFIVolume` instances: empty, + data and closed-source. 6. Check if given UEFI Firmware Volume is an NVAR storage using - :meth:`uefi.UEFIVolume._is_nvar_store_volume`. The volume is considered an - NVAR storage if at least 90% (currently defined as 90% by - :const:`uefi.UEFIVolume.NVAR_VOLUME_THRESHOLD`) of the volume entries are - ``NVAR entry``. + [UEFIVolume._is_nvar_store_volume][uv_is_nvar_store_volume]. The volume is + considered an NVAR storage if at least 90% (currently defined as 90% by + [UEFIVolume.NVAR_VOLUME_THRESHOLD][uv_nvar_vol_th]) of the volume entries are + `NVAR entry`. 7. If the volume is an NVAR storage, the difference between the volume size and classified entries size (so the unclassified bytes) are added up to the data group. Otherwise, if the volume is not NVAR storage, it must contain @@ -82,10 +79,9 @@ performs the following steps: At this point the UEFI Firmware Volume metrics are ready to be included in total calculations in step 4 of -`Calculating Dasharo Openness Score for UEFI images`_. +[Calculating Dasharo Openness Score for UEFI images](#calculating-dasharo-openness-score-for-uefi-images). -Calculating Dasharo Openness Score for coreboot images ------------------------------------------------------- +## Calculating Dasharo Openness Score for coreboot images coreboot images are processed with cbfstool and the output of cbfstool is parsed by the utility to make decisions about the image components. The @@ -94,41 +90,41 @@ calculation flow looks as follows: 1. Parse the flashmap layout printed by cbfstool and extract regions' attributes. 2. For each flashmap region containing CBFS, create a new instance of - :class:`coreboot.CBFSImage` and save it to an array. Creating new instance - of :class:`coreboot.CBFSImage` triggers the CBFS image calculations - described in section `Calculating metrics for CBFS images`_. + [coreboot.CBFSImage][cb_cbfsimage] and save it to an array. Creating new instance + of `CBFSImage` triggers the CBFS image calculations described in section + [Calculating metrics for CBFS images](#calculating-metrics-for-cbfs-images). 3. Start classifying regions: - * Skip regions containing CBFSes, they are calcululated inside - :class:`coreboot.CBFSImage` instances + * Skip regions containing CBFSes, they are calcululated inside `CBFSImage` + instances * Flashmap regions, which names are found in - :const:`coreboot.DasharoCorebootImage.CODE_REGIONS`, classify as + [coreboot.DasharoCorebootImage.CODE_REGIONS][cb_code_regions], classify as open-source. Currently the only region applicable is BOOTBLOCK. Some architectures do not store bootblock as a CBFS file but as flashmap region. * Flashmap regions, which names are found in - :const:`coreboot.DasharoCorebootImage.BLOB_REGIONS` (where regions known - to contain blobs are defined), classify as closed-source. + [coreboot.DasharoCorebootImage.BLOB_REGIONS][cb_blob_regions] (where + regions known to contain blobs are defined), classify as closed-source. * Flashmap regions, which names are found in - :const:`coreboot.DasharoCorebootImage.EMPTY_REGIONS`, classify as - empty. Currently only the ``UNUSED`` flashmap region name applies. + [coreboot.DasharoCorebootImage.EMPTY_REGIONS][cb_empty_regions], classify + as empty. Currently only the `UNUSED` flashmap region name applies. * Flashmap regions, which name is found in - :const:`coreboot.DasharoCorebootImage.DATA_REGIONS` (where regions known + [coreboot.DasharoCorebootImage.DATA_REGIONS][cb_data_regions] (where regions known to contain data only are defined), classify as data. * Flashmap regions, which names are found in - :const:`coreboot.DasharoCorebootImage.SKIP_REGIONS` are not classified - due to being cotnainers or aliases to other regions. Counting them would - result in duplication of the sizes when calculating metrics. These are - standard flashmap region names aggregating smaller, nested regions. + [coreboot.DasharoCorebootImage.SKIP_REGIONS][cb_skip_regions] are not + classified due to being cotnainers or aliases to other regions. Counting + them would result in duplication of the sizes when calculating metrics. + These are standard flashmap region names aggregating smaller, nested + regions. * If any region does not apply to above rules, save it in a separate array of uncategorized regions. It will be counted as closed-source in next step. 4. Sum up the size of all region groups: empty, data, open-source and closed-source. Add the sum of uncategorized regions to closed-source. -5. Sum up the size of all groups from all :class:`coreboot.CBFSImage` - instances saved in the array previously: empty, data, open-source and - closed-source. +5. Sum up the size of all groups from all `CBFSImage` instances saved in the + array previously: empty, data, open-source and closed-source. 6. Check if the first flashmap region offset in flash starts at 0. If yes, then do nothing. Otherwise count all bytes from 0 to the given offset as closed-source (we don't know what lies before the first flashmap region, it @@ -136,17 +132,15 @@ calculation flow looks as follows: 7. Check if all classified components sizes (empty, data, open-source and closed-source) calculated in point 4-6 sum up to the full image size. If not, print a warning. -8. Export the data to markdown and pie charts using the - :meth:`coreboot.DasharoCorebootImage.export_markdown`. +8. Export the data to markdown and pie charts using + [coreboot.DasharoCorebootImage.export_markdown][cb_export_markdown]. -Calculating metrics for CBFS images -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +### Calculating metrics for CBFS images Axiom: coreboot's payload is always assumed to be open-source (with a small exception known to Dasharo images which sometimes include EFI drivers for Ethernet NICs). - CBFS regions are processed with cbfstool and the output of cbfstool is parsed by the utility to make decisions about the CBFS components. The calculation flow looks as follows: @@ -167,14 +161,14 @@ calculation flow looks as follows: means it was built from source. * If iPXE was built from source, extract the PXE_ROM_ID Kconfig value and save the PCI ID used for the iPXE CBFS file name. If PXE_ROM_ID - not present, assume default ``10ec,8168``. + not present, assume default `10ec,8168`. 4. Check if external Ethernet NIC EFI driver was included: * Check if EDK2_LAN_ROM_DRIVER Kconfig value is set. If not, go to step 5. - * If yes, extract the ``fallback/payload`` from the CBFS and use + * If yes, extract the `fallback/payload` from the CBFS and use UEFIExtract on it to extract the file with - :attr:`coreboot.CBFSImage.DASHARO_LAN_ROM_GUID`. + [coreboot.CBFSImage.DASHARO_LAN_ROM_GUID][cbfsimage_dasharo_lan_from_guid]. * Compress the extracted EFI driver with LZMA to estimate the compressed size. * Save the size of compressed EFI driver for later calculations. @@ -183,29 +177,31 @@ calculation flow looks as follows: * CBFS files which type is found in - :const:`coreboot.CBFSImage.OPEN_SOURCE_FILETYPES` and names are not - found in :const:`coreboot.CBFSImage.CLOSED_SOURCE_EXCEPTIONS` classify + [coreboot.CBFSImage.OPEN_SOURCE_FILETYPES][cbfsimage_os_filetypes] and + names are not found in + [coreboot.CBFSImage.CLOSED_SOURCE_EXCEPTIONS][cbfsimage_cs_exceptions] + classify as open-source. + * CBFS files of type `raw`, which names are found in + [coreboot.CBFSImage.RAW_OPEN_SOURCE_FILES][cbfsimage_raw_os_files] classify as open-source. - * CBFS files of type ``raw``, which names are found in - :const:`coreboot.CBFSImage.RAW_OPEN_SOURCE_FILES` classify as - open-source. * If the iPXE was detected to be built from source and included as legacy - OptionROM CBFS file, classify ``pci.rom`` as open-source. + OptionROM CBFS file, classify `pci.rom` as open-source. * CBFS files which names are found in - :const:`coreboot.CBFSImage.CLOSED_SOURCE_FILETYPES`, classify as - closed-source. or with CBFS file's type found in - * CBFS files which type is found in - :const:`coreboot.CBFSImage.OPEN_SOURCE_FILETYPES` and name is found in - :const:`coreboot.CBFSImage.CLOSED_SOURCE_EXCEPTIONS`, classify as + [coreboot.CBFSImage.CLOSED_SOURCE_FILETYPES][cbfsimage_cs_filetypes], + classify as closed-source. or with CBFS file's type found in + * CBFS files which type is found in `CBFSImage.OPEN_SOURCE_FILETYPES` and + name is found in `CBFSImage.CLOSED_SOURCE_EXCEPTIONS`, classify as closed-source. - * CBFS files of type ``raw`` which names are found in - :const:`coreboot.CBFSImage.RAW_CLOSED_SOURCE_FILES`, classify as - close-source. - * CBFS files with type ``null`` classify as empty. + * CBFS files of type `raw` which names are found in + [coreboot.CBFSImage.RAW_CLOSED_SOURCE_FILES][cbfsimage_raw_cs_files], + classify as close-source. + * CBFS files with type `null` classify as empty. * CBFS files which type is found in - :const:`coreboot.CBFSImage.DATA_FILETYPES` classify as data. - * CBFS files of type ``raw`` and names found in - :const:`coreboot.CBFSImage.RAW_DATA_FILES` classify as data. + [coreboot.CBFSImage.DATA_FILETYPES][cbfsimage_data_filetypes] classify as + data. + * CBFS files of type `raw` and names found in + [coreboot.CBFSImage.RAW_DATA_FILES][cbfsimage_raw_data_files] classify as + data. * CBFS files not applying to above rules should be save to an array of uncategorized files. They will be counted as closed-source code in next steps because we were unable to identify what can be inside. @@ -230,4 +226,26 @@ calculation flow looks as follows: At this point the CBFS image metrics are ready to be included in total calculations in step 5 of -`Calculating Dasharo Openness Score for coreboot images`_. +[Calculating Dasharo Openness Score for coreboot images](#calculating-dasharo-openness-score-for-coreboot-images). + +[uefivolume]: ./uefi.md#openness_score.uefi.UEFIVolume +[uv_export_markdown]: ./uefi.md#openness_score.uefi.UEFIVolume.export_markdown +[uv_is_nvar_store_volume]: ./uefi.md#openness_score.uefi.UEFIVolume._is_nvar_store_volume +[uv_nvar_vol_th]: ./uefi.md#openness_score.uefi.UEFIVolume.NVAR_VOLUME_THRESHOLD +[cb_cbfsimage]: ./coreboot.md#openness_score.coreboot.CBFSImage +[cb_code_regions]: ./coreboot.md#openness_score.coreboot.DasharoCorebootImage.CODE_REGIONS +[cb_blob_regions]: ./coreboot.md#openness_score.coreboot.DasharoCorebootImage.BLOB_REGIONS +[cb_empty_regions]: ./coreboot.md#openness_score.coreboot.DasharoCorebootImage.EMPTY_REGIONS +[cb_data_regions]: ./coreboot.md#openness_score.coreboot.DasharoCorebootImage.DATA_REGIONS +[cb_skip_regions]: ./coreboot.md#openness_score.coreboot.DasharoCorebootImage.SKIP_REGIONS +[cb_export_markdown]: ./coreboot.md#openness_score.coreboot.DasharoCorebootImage.export_markdown +[cbfsimage_dasharo_lan_from_guid]: ./coreboot.md#openness_score.coreboot.CBFSImage.DASHARO_LAN_ROM_GUID +[cbfsimage_os_filetypes]: ./coreboot.md#openness_score.coreboot.CBFSImage.OPEN_SOURCE_FILETYPES +[cbfsimage_cs_exceptions]: ./coreboot.md#openness_score.coreboot.CBFSImage.CLOSED_SOURCE_EXCEPTIONS +[cbfsimage_raw_os_files]: ./coreboot.md#openness_score.coreboot.CBFSImage.RAW_OPEN_SOURCE_FILES +[cbfsimage_cs_filetypes]: ./coreboot.md#openness_score.coreboot.CBFSImage.CLOSED_SOURCE_FILETYPES +[cbfsimage_raw_cs_files]: ./coreboot.md#openness_score.coreboot.CBFSImage.RAW_CLOSED_SOURCE_FILES +[cbfsimage_data_filetypes]: ./coreboot.md#openness_score.coreboot.CBFSImage.DATA_FILETYPES +[cbfsimage_raw_data_files]: ./coreboot.md#openness_score.coreboot.CBFSImage.RAW_DATA_FILES + + diff --git a/docs/openness_score.md b/docs/openness_score.md new file mode 100644 index 0000000..c5a1af0 --- /dev/null +++ b/docs/openness_score.md @@ -0,0 +1,5 @@ +::: openness_score.openness_score + handler: python + options: + filters: [] + docstring_style: sphinx diff --git a/docs/source/conf.py b/docs/source/conf.py deleted file mode 100644 index d624da1..0000000 --- a/docs/source/conf.py +++ /dev/null @@ -1,37 +0,0 @@ -# Configuration file for the Sphinx documentation builder. -# -# For the full list of built-in configuration values, see the documentation: -# https://www.sphinx-doc.org/en/master/usage/configuration.html - -# -- Project information ----------------------------------------------------- -# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information - -project = 'Dasharo Openness Score' -copyright = '2023, Dasharo Team' -author = 'Dasharo Team' -release = 'v0.1.0' - -# -- General configuration --------------------------------------------------- -# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration - -extensions = [] - -templates_path = ['_templates'] -exclude_patterns = [] - - - -# -- Options for HTML output ------------------------------------------------- -# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output - -html_theme = 'sphinx_rtd_theme' -html_static_path = ['_static'] - - -import os -import sys - -sys.path.insert(0, os.path.abspath('../../openness_score/')) - -extensions.append('sphinx.ext.autodoc') -extensions.append('sphinx.ext.viewcode') diff --git a/docs/source/coreboot.rst b/docs/source/coreboot.rst deleted file mode 100644 index 0646f5c..0000000 --- a/docs/source/coreboot.rst +++ /dev/null @@ -1,11 +0,0 @@ -coreboot module -=============== - -.. automodule:: coreboot - :members: - :member-order: bysource - :exclude-members: __weakref__ - :private-members: - :special-members: - :show-inheritance: - :no-value: diff --git a/docs/source/index.rst b/docs/source/index.rst deleted file mode 100644 index ed77cb9..0000000 --- a/docs/source/index.rst +++ /dev/null @@ -1,55 +0,0 @@ -.. Dasharo Openness Score documentation master file, created by - sphinx-quickstart on Fri May 19 17:08:44 2023. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -Welcome to Dasharo Openness Score's documentation! -================================================== - -.. toctree:: - :maxdepth: 2 - :caption: Contents: - - methodology - design - modules - -What is Dasharo Openness Score -============================== - -Have you ever wondered how open is your open-source firmware? How much -closed-source and binary blobs is still there? Dasharo Openness Score utility -answers those questions. - -Dasharo Openness is a report showing the open-source code to closed-source -code ratio in the Dasharo firmware images. The results are also presented as a -pie chart for better visual representation of the firmware image components -and their share percentage. - -Dasharo Openness Score utility is capable of parsing Dasharo coreboot-based -images as well as vendor UEFI images. Thanks to that one can easily compare -how many bytes of the firmware have been liberated as well as by how much the -Trusted Computing Base (TCB) has been reduced. - -Dasharo Openness Score utility not only support Dasharo coreboot-based images, -but also many more coreboot distributions like heads. - -How does it work? -================= - -The utility leverages various tools like `coreboot's cbfstool`_ or -`LongSoft's UEFIExtract`_ to decompose and parse the firmware images. The -output from the utilities is used to detect the image type and then to -calculate the openness metrics. - -For more details please refer to the :doc:`methodology document `. - -.. _coreboot's cbfstool: https://github.com/coreboot/coreboot/tree/master/util/cbfstool -.. _LongSoft's UEFIExtract: https://github.com/LongSoft/UEFITool - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` diff --git a/docs/source/modules.rst b/docs/source/modules.rst deleted file mode 100644 index df1e76b..0000000 --- a/docs/source/modules.rst +++ /dev/null @@ -1,9 +0,0 @@ -Dasharo Openness Score modules documentation -============================================ - -.. toctree:: - :maxdepth: 4 - - openness_score - coreboot - uefi diff --git a/docs/source/openness_score.rst b/docs/source/openness_score.rst deleted file mode 100644 index 149fc99..0000000 --- a/docs/source/openness_score.rst +++ /dev/null @@ -1,7 +0,0 @@ -openness_score module -====================== - -.. automodule:: openness_score - :members: - :show-inheritance: - :no-value: diff --git a/docs/source/uefi.rst b/docs/source/uefi.rst deleted file mode 100644 index affb2fd..0000000 --- a/docs/source/uefi.rst +++ /dev/null @@ -1,11 +0,0 @@ -UEFI module -=========== - -.. automodule:: uefi - :members: - :member-order: bysource - :exclude-members: __weakref__ - :private-members: - :special-members: - :show-inheritance: - :no-value: diff --git a/docs/uefi.md b/docs/uefi.md new file mode 100644 index 0000000..4c8130a --- /dev/null +++ b/docs/uefi.md @@ -0,0 +1,6 @@ +::: openness_score.uefi + handler: python + options: + filters: [] + docstring_style: sphinx + diff --git a/make.bat b/make.bat deleted file mode 100644 index 4844689..0000000 --- a/make.bat +++ /dev/null @@ -1,39 +0,0 @@ -@ECHO OFF - -pushd %~dp0 - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set SOURCEDIR=docs\source -set BUILDDIR=build - -%SPHINXBUILD% >NUL 2>NUL -if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.https://www.sphinx-doc.org/ - exit /b 1 -) - -if "%1" == "" goto help -if "%1" == "livehtml" goto help - -%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% -goto end - -:help -%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% - -:livehtml -sphinx-autobuild %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% - -:end -popd diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 0000000..e49866e --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,17 @@ +--- +site_name: Openness Score +theme: + name: readthedocs + +plugins: + - search + - mkdocstrings + +nav: + - Home: index.md + - Methodology: methodology.md + - Design: design.md + - API Reference: + - openness_score: openness_score.md + - coreboot: coreboot.md + - uefi: uefi.md diff --git a/openness_score/coreboot.py b/openness_score/coreboot.py index 38b6330..ff8c3b9 100644 --- a/openness_score/coreboot.py +++ b/openness_score/coreboot.py @@ -71,8 +71,8 @@ def __init__(self, image_path, verbose=False): Initializes the class fields for storing the firmware image components classified to specific groups. Also calls - :meth:`~coreboot.DasharoCorebootImage._parse_cb_fmap_layout` and - :meth:`~coreboot.DasharoCorebootImage._calculate_metrics` methods to + `coreboot.DasharoCorebootImage._parse_cb_fmap_layout` and + `coreboot.DasharoCorebootImage._calculate_metrics` methods to parse the image and calculate the metrics. :param image_path: Path the the firmware image file being parsed. @@ -182,13 +182,13 @@ def _parse_cb_fmap_layout(self): Parses the output of 'cbfstool self.image_path layout -w' and extract the flashmap regions to a self.fmap_regions dictionary using the - :const:`coreboot.DasharoCorebootImage.region_regexp` regular + `coreboot.DasharoCorebootImage.region_regexp` regular expression. If a flashmap region has a CBFS attribute, the self.cbfs_images list is appended with a new instance of :class:`coreboot.CBFSImage`. - If :attr:`coreboot.DasharoCorebootImage.debug` is True, all flashmap + If `coreboot.DasharoCorebootImage.debug` is True, all flashmap regions with their attributes are printed on the console at the end. """ cmd = ['cbfstool', self.image_path, 'layout', '-w'] @@ -263,29 +263,29 @@ def _classify_region(self, region): categories and appended to respective lists. CBFS regions are processed separately and not included here. - :attr:`coreboot.DasharoCorebootImage.open_code_regions` are appended + `coreboot.DasharoCorebootImage.open_code_regions` are appended with flashmap regions which name is found in - :const:`coreboot.DasharoCorebootImage.CODE_REGIONS` + `coreboot.DasharoCorebootImage.CODE_REGIONS` - :attr:`coreboot.DasharoCorebootImage.closed_code_regions` are appended + `coreboot.DasharoCorebootImage.closed_code_regions` are appended with flashmap regions which name is found in - :const:`coreboot.DasharoCorebootImage.BLOB_REGIONS` + `coreboot.DasharoCorebootImage.BLOB_REGIONS` - :attr:`coreboot.DasharoCorebootImage.empty_regions` are appended with + `coreboot.DasharoCorebootImage.empty_regions` are appended with flashmap regions which name is found in - :const:`coreboot.DasharoCorebootImage.EMPTY_REGIONS` + `coreboot.DasharoCorebootImage.EMPTY_REGIONS` - :attr:`coreboot.DasharoCorebootImage.data_regions` are appended with + `coreboot.DasharoCorebootImage.data_regions` are appended with flashmap regions which name is found in - :const:`coreboot.DasharoCorebootImage.DATA_REGIONS` + `coreboot.DasharoCorebootImage.DATA_REGIONS` Flashmap regions which names is found in - :const:`coreboot.DasharoCorebootImage.SKIP_REGIONS` are not classified + `coreboot.DasharoCorebootImage.SKIP_REGIONS` are not classified due to being cotnainers or aliases to other regions. Counting them would result in duplication of the sizes when calculating metrics. Any other unrecognized flashmap region falls into - :attr:`coreboot.DasharoCorebootImage.data_regions` list which will be + `coreboot.DasharoCorebootImage.data_regions` list which will be counted as closed-source code region because we were unable to identify what can be inside. @@ -320,41 +320,41 @@ def _calculate_metrics(self): """Calculates the sizes of the four basic firmware components categories - Calls :meth:`~coreboot.DasharoCorebootImage._classify_region` for each + Calls `coreboot.DasharoCorebootImage._classify_region` for each detected region. The sums the regions sizes from all 5 lists - :attr:`coreboot.DasharoCorebootImage.open_code_regions` sizes sum is - added to :attr:`coreboot.DasharoCorebootImage.open_code_size` + `coreboot.DasharoCorebootImage.open_code_regions` sizes sum is + added to `coreboot.DasharoCorebootImage.open_code_size` - :attr:`coreboot.DasharoCorebootImage.closed_code_regions` sizes sum is - added to :attr:`coreboot.DasharoCorebootImage.closed_code_size` + `coreboot.DasharoCorebootImage.closed_code_regions` sizes sum is + added to `coreboot.DasharoCorebootImage.closed_code_size` - :attr:`coreboot.DasharoCorebootImage.data_regions` sizes sum is added - to :attr:`coreboot.DasharoCorebootImage.data_size` + `coreboot.DasharoCorebootImage.data_regions` sizes sum is added + to `coreboot.DasharoCorebootImage.data_size` - :attr:`coreboot.DasharoCorebootImage.empty_regions` sizes sum is added - to :attr:`coreboot.DasharoCorebootImage.empty_size` + `coreboot.DasharoCorebootImage.empty_regions` sizes sum is added + to `coreboot.DasharoCorebootImage.empty_size` - :attr:`coreboot.DasharoCorebootImage.uncategorized_regions` sizes sum - is added to :attr:`coreboot.DasharoCorebootImage.closed_code_size` + `coreboot.DasharoCorebootImage.uncategorized_regions` sizes sum + is added to `coreboot.DasharoCorebootImage.closed_code_size` Additionally for each detected CBFS region their four basic component's categories are also added to the total metrics. - :attr:`coreboot.CBFSImage.open_code_size` is added to - :attr:`coreboot.DasharoCorebootImage.open_code_size` + `coreboot.CBFSImage.open_code_size` is added to + `coreboot.DasharoCorebootImage.open_code_size` - :attr:`coreboot.CBFSImage.closed_code_size` is added to - :attr:`coreboot.DasharoCorebootImage.closed_code_size` + `coreboot.CBFSImage.closed_code_size` is added to + `coreboot.DasharoCorebootImage.closed_code_size` - :attr:`coreboot.CBFSImage.data_size` is added to - :attr:`coreboot.DasharoCorebootImage.data_size` + `coreboot.CBFSImage.data_size` is added to + `coreboot.DasharoCorebootImage.data_size` - :attr:`coreboot.CBFSImage.empty_size` is added to - :attr:`coreboot.DasharoCorebootImage.empty_size` + `coreboot.CBFSImage.empty_size` is added to + `coreboot.DasharoCorebootImage.empty_size` At the end the method calls - :meth:`coreboot.DasharoCorebootImage._normalize_sizes` + `coreboot.DasharoCorebootImage._normalize_sizes` """ for i in range(self.num_regions): self._classify_region(self.fmap_regions[i]) @@ -402,7 +402,7 @@ def _normalize_sizes(self): does not start at offset zero, which is possible for Intel board coreboot images without IFD and ME regions specified. In such case the missing regions are counted as closed-source and added to - :attr:`coreboot.DasharoCorebootImage.closed_code_size` + `coreboot.DasharoCorebootImage.closed_code_size` """ # It may happen that the FMAP does not cover whole flash size and the # first region will start with non-zero offset. Check if first region @@ -453,8 +453,8 @@ def export_markdown(self, file, mkdocs): Saves the parsed information and classified image components into a markdown file. Also for each CBFS in - :attr:`coreboot.DasharoCorebootImage.cbfs_images` it calls - :meth:`coreboot.CBFSImage.export_markdown` to save the CBFS region + `coreboot.DasharoCorebootImage.cbfs_images` it calls + `coreboot.CBFSImage.export_markdown` to save the CBFS region statistics. :param file: Path to markdown file @@ -680,9 +680,9 @@ def __init__(self, image_path, region, verbose=False): Initializes the class fields for storing the CBFS region components classified to specific groups. Also calls - :meth:`~coreboot.DasharoCorebootImage._parse_cbfs_files`, - :meth:`~coreboot.DasharoCorebootImage._parse_cb_config` and - :meth:`~coreboot.DasharoCorebootImage._calculate_metrics` methods to + `coreboot.DasharoCorebootImage._parse_cbfs_files`, + `coreboot.DasharoCorebootImage._parse_cb_config` and + `coreboot.DasharoCorebootImage._calculate_metrics` methods to parse the CBFS and calculate the metrics. :param region: Path the the firmware image file being parsed. @@ -794,13 +794,13 @@ def __str__(self): def _parse_cbfs_files(self): """Parses the CBFS contents from cbfstool output - Parses the output of 'cbfstool :attr:`coreboot.CBFSImage.image_path` - print -r :attr:`coreboot.CBFSImage.region_name`' and extracts the CBFS - files information to the :attr:`coreboot.CBFSImage.cbfs_files` - dictionary using the :const:`coreboot.CBFSImage.file_regexp` regular + Parses the output of 'cbfstool `coreboot.CBFSImage.image_path` + print -r `coreboot.CBFSImage.region_name`' and extracts the CBFS + files information to the `coreboot.CBFSImage.cbfs_files` + dictionary using the `coreboot.CBFSImage.file_regexp` regular expression. - If :attr:`coreboot.CBFSImage.debug` is True, all CBFS contents with + If `coreboot.CBFSImage.debug` is True, all CBFS contents with their attributes are printed on the console at the end. """ cmd = ['cbfstool', self.image_path, 'print', '-r', self.region_name] @@ -825,30 +825,30 @@ def _calculate_metrics(self): """Calculates the sizes of the four basic firmware components categories - Calls :meth:`~coreboot.CBFSImage._classify_file` for each detected + Calls `coreboot.CBFSImage._classify_file` for each detected CBFS file. Then sums the files' sizes from all 5 lists: - :attr:`coreboot.CBFSImage.open_code_files` sizes sum is added to - :attr:`coreboot.CBFSImage.open_code_size` + `coreboot.CBFSImage.open_code_files` sizes sum is added to + `coreboot.CBFSImage.open_code_size` - :attr:`coreboot.CBFSImage.closed_code_files` sizes sum is added to - :attr:`coreboot.CBFSImage.closed_code_size` + `coreboot.CBFSImage.closed_code_files` sizes sum is added to + `coreboot.CBFSImage.closed_code_size` - :attr:`coreboot.CBFSImage.data_files` sizes sum is added to - :attr:`coreboot.CBFSImage.data_size` + `coreboot.CBFSImage.data_files` sizes sum is added to + `coreboot.CBFSImage.data_size` - :attr:`coreboot.CBFSImage.empty_files` sizes sum is added to - :attr:`coreboot.CBFSImage.empty_size` + `coreboot.CBFSImage.empty_files` sizes sum is added to + `coreboot.CBFSImage.empty_size` - :attr:`coreboot.CBFSImage.uncategorized_files` sizes sum is added to - :attr:`coreboot.CBFSImage.closed_code_size` + `coreboot.CBFSImage.uncategorized_files` sizes sum is added to + `coreboot.CBFSImage.closed_code_size` Additionally if a LAN EFI driver has been detected, it is subtracted from open-source code size (normally the driver is part ofthe payload considered to be open-source) and added to the closed-source size. At the end the method calls - :meth:`coreboot.CBFSImage._normalize_sizes` + `coreboot.CBFSImage._normalize_sizes` """ for i in range(self.num_files): self._classify_file(self.cbfs_files[i]) @@ -882,33 +882,33 @@ def _classify_file(self, file): Each detected CBFS file is being classified into 4 basic categories and appended to respective lists. - :attr:`coreboot.CBFSImage.open_code_files` are appended with CBFS + `coreboot.CBFSImage.open_code_files` are appended with CBFS files which type is found in - :const:`coreboot.CBFSImage.OPEN_SOURCE_FILETYPES` and names are not - found in :const:`coreboot.CBFSImage.CLOSED_SOURCE_EXCEPTIONS`. CBFS + `coreboot.CBFSImage.OPEN_SOURCE_FILETYPES` and names are not + found in `coreboot.CBFSImage.CLOSED_SOURCE_EXCEPTIONS`. CBFS files of type 'raw' are also classified as open-source code if its - name is found in :const:`coreboot.CBFSImage.RAW_OPEN_SOURCE_FILES` or + name is found in `coreboot.CBFSImage.RAW_OPEN_SOURCE_FILES` or if it is an iPXE legacy ROM (based on the PCI ID detected from coreboot's config). - :attr:`coreboot.CBFSImage.closed_code_files` are appended with CBFS + `coreboot.CBFSImage.closed_code_files` are appended with CBFS files which name is found in - :const:`coreboot.CBFSImage.CLOSED_SOURCE_FILETYPES` or with CBFS - file's type found in :const:`coreboot.CBFSImage.OPEN_SOURCE_FILETYPES` - and name found in :const:`coreboot.CBFSImage.CLOSED_SOURCE_EXCEPTIONS` + `coreboot.CBFSImage.CLOSED_SOURCE_FILETYPES` or with CBFS + file's type found in `coreboot.CBFSImage.OPEN_SOURCE_FILETYPES` + and name found in `coreboot.CBFSImage.CLOSED_SOURCE_EXCEPTIONS` or with CBFS files of type 'raw' which names are found in - :const:`coreboot.CBFSImage.RAW_CLOSED_SOURCE_FILES`. + `coreboot.CBFSImage.RAW_CLOSED_SOURCE_FILES`. - :attr:`coreboot.CBFSImage.empty_files` are appended with CBFS files + `coreboot.CBFSImage.empty_files` are appended with CBFS files with type 'null'. - :attr:`coreboot.CBFSImage.data_files` are appended with CBFS files - which type is found in :const:`coreboot.CBFSImage.DATA_FILETYPES` or + `coreboot.CBFSImage.data_files` are appended with CBFS files + which type is found in `coreboot.CBFSImage.DATA_FILETYPES` or with CBFS file of type 'raw' and names found in - :const:`coreboot.CBFSImage.RAW_DATA_FILES`. + `coreboot.CBFSImage.RAW_DATA_FILES`. Any other unrecognized CBFS files fall into - :attr:`coreboot.CBFSImage.uncategorized_files` list which will be + `coreboot.CBFSImage.uncategorized_files` list which will be counted as closed-source code because we were unable to identify what can be inside. @@ -953,13 +953,13 @@ def _normalize_sizes(self): byte offset of the end of last file in CBFS and calculate the truncated size by subtracting the offset from the CBFS region size. The truncated size is then added to the - :attr:`coreboot.CBFSImage.empty_size`. + `coreboot.CBFSImage.empty_size`. cbfstool prints only the sizes of files and does not account for the metadata surrounding the file. It is necessary to calculate the metadata size by subtarcting all file's sizes from the whole CBFS region size. The metadata size is then added to the - :attr:`coreboot.CBFSImage.data_size`. + `coreboot.CBFSImage.data_size`. """ # We have to take into account truncated CBFSes like FW_MAIN_A or # FW_MAIN_B, where the space after the last file is empty but not @@ -1019,11 +1019,11 @@ def _parse_cb_config(self): The function uses the cbfstool to extract the coreboot's config and a regexp to extract the Kconfig names and values to - :attr:`coreboot.CBFSImage.kconfig_opts`. + `coreboot.CBFSImage.kconfig_opts`. Additionally the function calls - :meth:`coreboot.CBFSImage._check_for_ipxe` and - :meth:`coreboot.CBFSImage._check_for_lanrom`. + `coreboot.CBFSImage._check_for_ipxe` and + `coreboot.CBFSImage._check_for_lanrom`. """ kconfig_pattern = r'^CONFIG_(?P