From 4c6defc8969665f624e3ee86eb5fa0e8822b9bd0 Mon Sep 17 00:00:00 2001 From: Fabian Wienand Date: Tue, 5 Aug 2025 15:47:26 +0200 Subject: [PATCH] feat: add base & chipsec image targets & modules Signed-off-by: Fabian Wienand --- .commitlintrc.yml | 19 +++ .envrc | 1 + .github/workflows/commitlint.yml | 11 ++ .github/workflows/nix.yml | 34 +++++ .gitignore | 8 +- Makefile | 12 ++ README.md | 205 ++++++++++++++++++++++++++++++- flake.lock | 135 ++++++++++++++++++++ flake.nix | 122 ++++++++++++++++++ modules/base.nix | 123 +++++++++++++++++++ modules/default-tools.nix | 18 +++ modules/kernel.nix | 50 ++++++++ pkgs/chipsec/compile-ko.diff | 13 ++ pkgs/chipsec/default.nix | 95 ++++++++++++++ pkgs/chipsec/ko-path.diff | 13 ++ pkgs/default-tools/default.nix | 38 ++++++ statix.toml | 4 + 17 files changed, 897 insertions(+), 4 deletions(-) create mode 100644 .commitlintrc.yml create mode 100644 .envrc create mode 100644 .github/workflows/commitlint.yml create mode 100644 .github/workflows/nix.yml create mode 100644 Makefile create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 modules/base.nix create mode 100644 modules/default-tools.nix create mode 100644 modules/kernel.nix create mode 100644 pkgs/chipsec/compile-ko.diff create mode 100644 pkgs/chipsec/default.nix create mode 100644 pkgs/chipsec/ko-path.diff create mode 100644 pkgs/default-tools/default.nix create mode 100644 statix.toml diff --git a/.commitlintrc.yml b/.commitlintrc.yml new file mode 100644 index 0000000..5a79aa0 --- /dev/null +++ b/.commitlintrc.yml @@ -0,0 +1,19 @@ +# Configuration for commitlint +--- +# Basic set of roules taken from https://github.com/conventional-changelog/commitlint/tree/master/%40commitlint/config-conventional +extends: + - "@commitlint/config-conventional" +# Override type-enum to just use types, which are relevant to this project +rules: + type-enum: + - 2 + - always + - - build + - chore + - ci + - docs + - feat + - fix + - refactor + - revert + - test diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..8392d15 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use flake \ No newline at end of file diff --git a/.github/workflows/commitlint.yml b/.github/workflows/commitlint.yml new file mode 100644 index 0000000..fe56479 --- /dev/null +++ b/.github/workflows/commitlint.yml @@ -0,0 +1,11 @@ +name: Commits +on: [pull_request] + +jobs: + commitlint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: wagoid/commitlint-github-action@v6 diff --git a/.github/workflows/nix.yml b/.github/workflows/nix.yml new file mode 100644 index 0000000..ec9a950 --- /dev/null +++ b/.github/workflows/nix.yml @@ -0,0 +1,34 @@ +name: Nix Flake CI + +on: + push: + branches: [main] + pull_request: + +jobs: + nix: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install Nix + uses: cachix/install-nix-action@v31 + with: + extra_nix_config: | + experimental-features = nix-command flakes + + - name: Lint Nix code with statix + run: nix run .#statix -- check . + + - name: Format check with nixpkgs-fmt + run: nix run .#nixpkgs-fmt -- --check . + + - name: Flake check + run: nix flake check --show-trace + + - name: Build base image + run: nix build .#base + + - name: Build chipsec image + run: nix build .#chipsec diff --git a/.gitignore b/.gitignore index 912e670..fba377d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,10 @@ # Ignore build outputs from performing a nix-build or `nix build` command -result -result-* +result* +base +chipsec # Ignore automatically generated direnv output .direnv + +# Ignore hooks +.pre-commit-config.yaml \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..6c4d6b0 --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ +TARGETS = base chipsec + +all: $(TARGETS) + +$(TARGETS): + nix build .#$@ --out-link $@ + +clean: + rm -f $(TARGETS) + +.NOTPARALLEL: all $(TARGETS) +.PHONY: all clean $(TARGETS) \ No newline at end of file diff --git a/README.md b/README.md index c787869..3e54d43 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,203 @@ -# fwci-base-image -This repository provides a minimal, NixOS-based image designed to serve as a base environment for FirmwareCI tests. It equips the host machine with all necessary capabilities required for running the tests. +# FirmwareCI Base Image + +This repository provides **modular, reproducible NixOS base images** for FirmwareCI and custom hardware testing. It is intended as a robust foundation for building your own NixOS-based CI images, offering flexible configuration of kernel, firmware, packages, and services. Each image includes essential default tooling, enabling your host machine to execute any FirmwareCI test step reliably. + +**Note:** Chipsec requires an older kernel version for compatibility. To run the chipsec test step, use the provided chipsec configuration or image, which is preconfigured with the appropriate kernel. + +For a comprehensive overview of available FirmwareCI commands and usage, refer to the [FirmwareCI Commands Reference](https://docs.firmware-ci.com/references/2_commands/index.html). + +## Features + +- **Nix Flake-based**: Modern, reproducible, and composable. +- **Easy to extend**: Use as a base for your own hardware. + +--- + +## Quick Start + +### Prerequisites + +- [Nix](https://nixos.org/download.html) with flakes enabled (`experimental-features = nix-command flakes` in your `nix.conf`). + +### Build All Images + +```sh +make all +``` + +### Build a Specific Image + +```sh +make base +make chipsec +``` + +### Clean build outputs + +```sh +make clean +``` + +The resulting images will be symlinked as `./base` and `./chipsec`. + +--- + +## Flake Structure + +- `flake.nix` – Flake entrypoint, exposes base and chipsec images as outputs. +- `modules/base.nix` – Base system options and configuration. +- `modules/kernel.nix` – Kernel options and configuration. +- `pkgs/default-tools/default.nix` – Default fwci testing tools package. +- `Makefile` – Simple build automation for images. + +--- + +## Using as a Base for Your Own Image + +You can use this flake as a base for your own NixOS image or configuration. + +### Example: Extend in Your Own Flake + +```nix +{ + description = "My Custom FirmwareCI Image"; + + inputs.firmwareci-base-image.url = "github:BlindspotSoftware/firmwareci-base-image"; + + outputs = { self, nixpkgs, firmwareci-base-image, ... }: + let + myHardwareConfig = { ... }: { + firmwareci.base = { + sshAccess = { + user = "root"; + key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKcSD9iHnCrJXkSt7aGSnfL0tVHUm+x6/EDr/FchmBfu"; + }; + }; + + firmwareci.kernel = { + version = "6.6.7"; + sha256 = "..."; + extraKernelModules = [ "dummy" "loop" ]; + }; + }; + in { + nixosConfigurations.my-custom-image = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + modules = [ + firmwareci-base-image.baseConfig + myHardwareConfig + ]; + }; + }; +} +``` + +--- + +## Configuration Options + +You can override these options in your own configuration or flake: + +### **firmwareci.base options** + +| Option | Type | Default | Description | +|-------------------|-----------|--------------------------------|-----------------------------------------------------| +| `sshAccess` | submodule | `{ user = ""; key = ""; }` | Add an SSH public key for a user (see below). | +| `enableFwupd` | bool | `true` | Enable the fwupd firmware update service. | +| `enableAllFirmware` | bool | `true` | Enable all available firmware blobs. | +| `allowBroken` | bool | `true` | Allow installation of broken packages. | +| `allowUnfree` | bool | `true` | Allow installation of unfree packages. | +| `includeChipSec` | bool | `false` | Include chipsec with kernel module (<= 6.12 only). | +| `includeDefaultTools` | bool | `true` | Include the default tools package in the image. | + +#### `sshAccess` submodule + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `user` | str | `""` | SSH user for access (e.g. `"root"`). | +| `key` | str | `""` | SSH public key to add to the user's authorized_keys. | + +### **firmwareci.kernel options** + +| Option | Type | Default | Description | +|---------------------------|---------------------|-----------|---------------------------------------------------------------------------------------------| +| `version` | `str` | `"6.15.8"`| Linux kernel version to use. | +| `sha256` | `str` | SRI hash | sha256 hash for the kernel tarball (must be in SRI format, e.g. `sha256-...`). | +| `extraKernelModules` | `list of str` | `[]` | Extra kernel modules to load at boot (e.g. `["dummy"]`). | + +--- + +## SSH Access and Security + +**Note:** +The default FirmwareCI images are configured to allow SSH access to the root user: + +```nix +users.users.root.openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKcSD9iHnCrJXkSt7aGSnfL0tVHUm+x6/EDr/FchmBfu" +]; +``` + +This configuration allows FirmwareCI to securely connect to your device via SSH using a preconfigured key at `/root/.ssh/fwci` inside the test environment. You may also customize the SSH access settings to suit your specific requirements. + +Example SSH transport configuration for FirmwareCI to connect to the machine: + +```yaml +transport: &transport + proto: ssh + options: + host: "my.network" + user: root + identity_file: /root/.ssh/fwci #pre-configured SSH-key +``` + +**Caution:** +Do not enable this configuration on devices connected to publicly accessible networks, as it may expose your system to unauthorized access. + +--- + +## Structure + +- `flake.nix` – Flake entrypoint, exposes base and chipsec images. +- `modules/base.nix` – Base system options and configuration. +- `modules/kernel.nix` – Kernel options and configuration. +- `pkgs/default-tools/default.nix` – Default fwci testing tools package. +- `Makefile` – Simple build automation for images. + +--- + +## Development + +We welcome contributions from everyone! +Format and lint Nix code with: + +```sh +nix fmt +nix run .#statix +``` + +Pre-commit hooks are available via `pre-commit-hooks.nix` and will run `nixpkgs-fmt` and `statix` on all `.nix` files before commit. + +--- + +## License + +[BSD 2-Clause License](LICENSE) + +--- + +## Maintainers + +- [@BlindspotSoftware](https://github.com/orgs/BlindspotSoftware) + +--- + +## Contributing + +Contributions and issues are welcome! Please open a PR or issue on GitHub. + +--- + +## References + +- [NixOS](https://nixos.org/) diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..40fe7b8 --- /dev/null +++ b/flake.lock @@ -0,0 +1,135 @@ +{ + "nodes": { + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1747046372, + "narHash": "sha256-CIVLLkVgvHYbgI2UpXvIIBJ12HWgX+fjA8Xf8PUmqCY=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "9100a0f413b0c601e0533d1d94ffd501ce2e7885", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "gitignore": { + "inputs": { + "nixpkgs": [ + "pre-commit-hooks", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1709087332, + "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1755078291, + "narHash": "sha256-Hu/gTDoi4uy6TAKISPHQusSMy8U6xUbLSDjKBYdhDIY=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "3385ca0cd7e14c1a1eb80401fe011705ff012323", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-25.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1754340878, + "narHash": "sha256-lgmUyVQL9tSnvvIvBp7x1euhkkCho7n3TMzgjdvgPoU=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "cab778239e705082fe97bb4990e0d24c50924c04", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "pre-commit-hooks": { + "inputs": { + "flake-compat": "flake-compat", + "gitignore": "gitignore", + "nixpkgs": "nixpkgs_2" + }, + "locked": { + "lastModified": 1754416808, + "narHash": "sha256-c6yg0EQ9xVESx6HGDOCMcyRSjaTpNJP10ef+6fRcofA=", + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "rev": "9c52372878df6911f9afc1e2a1391f55e4dfc864", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs", + "pre-commit-hooks": "pre-commit-hooks" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..eac82d9 --- /dev/null +++ b/flake.nix @@ -0,0 +1,122 @@ +{ + description = "FirmwareCI Test Image"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05"; + flake-utils.url = "github:numtide/flake-utils"; + pre-commit-hooks.url = "github:cachix/pre-commit-hooks.nix"; + }; + + outputs = { self, flake-utils, nixpkgs, pre-commit-hooks, ... }: + let + fsType = "ext4"; + + # The general base config for reuse + baseConfig = { config, modulesPath, pkgs, ... }: { + imports = [ + "${modulesPath}/profiles/base.nix" + "${modulesPath}/profiles/minimal.nix" + "${modulesPath}/profiles/all-hardware.nix" + ./modules/base.nix + ./modules/kernel.nix + ]; + system.stateVersion = "25.05"; + time.timeZone = "Europe/Berlin"; + fileSystems."/" = { + inherit fsType; + device = "/dev/disk/by-label/nixos"; + }; + fileSystems."/boot/EFI" = { + device = "/dev/disk/by-label/ESP"; + }; + firmwareci.base = { + sshAccess = { + user = "root"; + key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKcSD9iHnCrJXkSt7aGSnfL0tVHUm+x6/EDr/FchmBfu"; + }; + }; + }; + + chipsecConfig = { config, modulesPath, pkgs, ... }: { + imports = [ + baseConfig + ]; + firmwareci = { + base = { + includeChipSec = true; + }; + kernel = { + version = "6.12.36"; + sha256 = "sha256-ShaK7S3lqBqt2QuisVOGCpjZm/w0ZRk24X8Y5U8Buow=="; + }; + }; + }; + + generateDiskImage = { config, fsType, pkgs }: + import "${nixpkgs}/nixos/lib/make-disk-image.nix" { + inherit config fsType pkgs; + inherit (nixpkgs) lib; + partitionTableType = "efi"; + additionalSpace = "0"; + }; + in + { + modules = { + base = import ./modules/base.nix; + kernel = import ./modules/kernel.nix; + }; + + inherit baseConfig chipsecConfig; + } // flake-utils.lib.eachSystem (with flake-utils.lib.system; [ x86_64-linux ]) + (system: + let + pkgs = import nixpkgs { + inherit system; + }; + nixosConfigurations = { + base = nixpkgs.lib.nixosSystem { + inherit system; + modules = [ baseConfig ]; + }; + + chipsec = nixpkgs.lib.nixosSystem { + inherit system; + modules = [ chipsecConfig ]; + }; + }; + in + { + checks = { + pre-commit-check = pre-commit-hooks.lib.${system}.run { + src = ./.; + hooks = { + nixpkgs-fmt.enable = true; + statix.enable = true; + }; + }; + }; + + devShells.default = pkgs.mkShell { + packages = with pkgs; [ statix ]; + shellHook = '' + ${self.checks.${system}.pre-commit-check.shellHook} + ''; + }; + + packages = { + inherit (pkgs) statix nixpkgs-fmt; + + base = generateDiskImage { + inherit fsType pkgs; + inherit (nixosConfigurations.base) config; + }; + + chipsec = generateDiskImage { + inherit fsType pkgs; + inherit (nixosConfigurations.chipsec) config; + }; + }; + + defaultPackage = self.packages.${system}.base; + }); +} diff --git a/modules/base.nix b/modules/base.nix new file mode 100644 index 0000000..302ed9b --- /dev/null +++ b/modules/base.nix @@ -0,0 +1,123 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.firmwareci.base; + + chipsecKernelVersion = "6.12.36"; + kernelPackages = pkgs.linuxPackagesFor (pkgs.linux_6_12.override { + argsOverride = rec { + kernelPatches = [ ]; + version = chipsecKernelVersion; + modDirVersion = chipsecKernelVersion; + src = pkgs.fetchurl { + url = "mirror://kernel/linux/kernel/v${lib.versions.major version}.x/linux-${version}.tar.xz"; + sha256 = "sha256-ShaK7S3lqBqt2QuisVOGCpjZm/w0ZRk24X8Y5U8Buow="; + }; + }; + }); + + chipsec = pkgs.callPackage ../pkgs/chipsec/default.nix { + kernel = kernelPackages.kernel; + withDriver = true; + }; + +in +{ + options.firmwareci.base = { + sshAccess = { + user = mkOption { + type = types.str; + default = ""; + description = "SSH user for access."; + }; + key = mkOption { + type = types.str; + default = ""; + description = "SSH public key for access."; + }; + }; + enableFwupd = mkOption { + type = types.bool; + default = true; + description = "Enable fwupd service."; + }; + enableAllFirmware = mkOption { + type = types.bool; + default = true; + description = "Enable all firmware blobs."; + }; + allowBroken = mkOption { + type = types.bool; + default = true; + description = "Allow installation of broken packages."; + }; + allowUnfree = mkOption { + type = types.bool; + default = true; + description = "Allow installation of unfree packages."; + }; + includeChipSec = mkOption { + type = types.bool; + default = false; + description = "Include chipsec with kernel module (only works with kernel <= 6.12)"; + }; + includeDefaultTools = mkOption { + type = types.bool; + default = true; + description = "Include the default tools package in the image."; + }; + + }; + + config = { + boot.loader = { + efi = { + canTouchEfiVariables = false; + }; + grub.enable = false; + systemd-boot.enable = true; + }; + + nixpkgs.config = { + allowBroken = mkDefault cfg.allowBroken; + allowUnfree = mkDefault cfg.allowUnfree; + }; + + + environment.systemPackages = with pkgs; [ + # FirmwareCI tools + acpica-tools + dmidecode + fwts + sbctl + s0ix-selftest-tool + config.boot.kernelPackages.turbostat + stress-ng + sysbench + bc + powertop + ] + ++ lib.optional cfg.includeChipSec chipsec + ++ lib.optional cfg.includeDefaultTools (pkgs.callPackage ../pkgs/default-tools/default.nix { }); + + hardware.enableAllFirmware = cfg.enableAllFirmware; + + services.openssh = mkIf (cfg.sshAccess.user != "" && cfg.sshAccess.key != "") { + enable = true; + settings.PermitRootLogin = if cfg.sshAccess.user == "root" then "yes" else "no"; + }; + + users.users.${cfg.sshAccess.user} = mkIf (cfg.sshAccess.user != "" && cfg.sshAccess.key != "") { + openssh.authorizedKeys.keys = [ cfg.sshAccess.key ]; + }; + + services.fwupd = mkIf cfg.enableFwupd { + enable = true; + daemonSettings = lib.mkForce { + EspLocation = "/boot/EFI"; + }; + }; + }; +} diff --git a/modules/default-tools.nix b/modules/default-tools.nix new file mode 100644 index 0000000..f8a5733 --- /dev/null +++ b/modules/default-tools.nix @@ -0,0 +1,18 @@ +# FirmwareCI job dependencies +{ config, lib, pkgs, ... }: + +let + defaultTools = pkgs.callPackage ../pkgs/default-tools/default.nix { }; +in +{ + environment.systemPackages = [ defaultTools ]; + + system.activationScripts.copyDefaultTools = { + deps = [ ]; + text = '' + mkdir -p /root + + cp -r ${defaultTools}/default-tools /root/ + ''; + }; +} diff --git a/modules/kernel.nix b/modules/kernel.nix new file mode 100644 index 0000000..de39424 --- /dev/null +++ b/modules/kernel.nix @@ -0,0 +1,50 @@ +{ config, lib, pkgs, ... }: + +# FirmwareCI kernel configuration + +with lib; + +let + cfg = config.firmwareci.kernel; +in +{ + options.firmwareci.kernel = { + version = mkOption { + type = types.str; + default = "6.15.8"; + description = "Linux kernel version to use"; + }; + sha256 = mkOption { + type = types.str; + default = "sha256-036SvBa5YqMCXfFWZHva2QsttP82x6YTeBf+ge8/KKY="; + description = "sha256 for the kernel tarball"; + }; + extraKernelModules = mkOption { + type = types.listOf types.str; + default = [ ]; + description = "Extra kernel modules to load at boot."; + }; + }; + + config = { + boot.kernelPackages = pkgs.linuxPackagesFor (pkgs.linux_latest.override { + argsOverride = rec { + inherit (cfg) version sha256; + modDirVersion = version; + src = pkgs.fetchurl { + url = "mirror://kernel/linux/kernel/v${lib.versions.major version}.x/linux-${version}.tar.xz"; + inherit sha256; + }; + }; + }); + + boot.kernelModules = [ + "msr" + "intel_rapl_common" + "intel_pmc_core" + "intel_lpss" + "intel_lpss_pci" + "intel_lpss_acpi" + ] ++ cfg.extraKernelModules; + }; +} diff --git a/pkgs/chipsec/compile-ko.diff b/pkgs/chipsec/compile-ko.diff new file mode 100644 index 0000000..2ac6f69 --- /dev/null +++ b/pkgs/chipsec/compile-ko.diff @@ -0,0 +1,13 @@ +diff --git a/setup.py b/setup.py +index 3465765c..ae128922 100755 +--- a/setup.py ++++ b/setup.py +@@ -137,7 +137,7 @@ class build_ext(_build_ext): + elif platform.system().lower() == "windows": + driver_build_function = self._build_win_driver + +- if not self.skip_driver: ++ if True: + driver_build_function() + + def get_source_files(self): diff --git a/pkgs/chipsec/default.nix b/pkgs/chipsec/default.nix new file mode 100644 index 0000000..61ff179 --- /dev/null +++ b/pkgs/chipsec/default.nix @@ -0,0 +1,95 @@ +{ lib +, stdenv +, fetchFromGitHub +, kernel ? null +, elfutils +, nasm +, python3 +, withDriver ? false +, +}: + +python3.pkgs.buildPythonApplication rec { + pname = "chipsec"; + version = "1.10.6"; + format = "setuptools"; + + disabled = !stdenv.hostPlatform.isLinux; + + src = fetchFromGitHub { + owner = "chipsec"; + repo = "chipsec"; + rev = version; + hash = "sha256-+pbFG1SmSO/cnt1e+kel7ereC0I1OCJKKsS0KaJDWdc="; + }; + + patches = lib.optionals withDriver [ + ./ko-path.diff + ./compile-ko.diff + ]; + + postPatch = '' + substituteInPlace tests/software/util.py \ + --replace-fail "assertRegexpMatches" "assertRegex" + ''; + + KSRC = lib.optionalString withDriver "${kernel.dev}/lib/modules/${kernel.modDirVersion}/build"; + + nativeBuildInputs = [ + nasm + ] + ++ lib.optionals (lib.meta.availableOn stdenv.buildPlatform elfutils) [ + elfutils + ] + ++ lib.optionals withDriver kernel.moduleBuildDependencies; + + nativeCheckInputs = with python3.pkgs; [ + distro + pytestCheckHook + ]; + + preBuild = lib.optionalString withDriver '' + export CHIPSEC_BUILD_LIB=$(mktemp -d) + mkdir -p $CHIPSEC_BUILD_LIB/chipsec/helper/linux + appendToVar setupPyBuildFlags "--build-lib=$CHIPSEC_BUILD_LIB" + ''; + + env.NIX_CFLAGS_COMPILE = toString [ + # Needed with GCC 12 + "-Wno-error=dangling-pointer" + ]; + + preInstall = lib.optionalString withDriver '' + mkdir -p $out/${python3.pkgs.python.sitePackages}/drivers/linux + mv $CHIPSEC_BUILD_LIB/chipsec/helper/linux/chipsec.ko \ + $out/${python3.pkgs.python.sitePackages}/drivers/linux/chipsec.ko + ''; + + setupPyBuildFlags = lib.optionals (!withDriver) [ + "--skip-driver" + ]; + + pythonImportsCheck = [ + "chipsec" + ]; + + meta = with lib; { + description = "Platform Security Assessment Framework"; + longDescription = '' + CHIPSEC is a framework for analyzing the security of PC platforms + including hardware, system firmware (BIOS/UEFI), and platform components. + It includes a security test suite, tools for accessing various low level + interfaces, and forensic capabilities. It can be run on Windows, Linux, + Mac OS X and UEFI shell. + ''; + license = licenses.gpl2Only; + homepage = "https://github.com/chipsec/chipsec"; + maintainers = with maintainers; [ + johnazoidberg + erdnaxe + ]; + platforms = [ "x86_64-linux" ] ++ lib.optional (!withDriver) "x86_64-darwin"; + # https://github.com/chipsec/chipsec/issues/1793 + broken = withDriver && kernel.kernelOlder "5.4" && kernel.isHardened; + }; +} diff --git a/pkgs/chipsec/ko-path.diff b/pkgs/chipsec/ko-path.diff new file mode 100644 index 0000000..b7f8f08 --- /dev/null +++ b/pkgs/chipsec/ko-path.diff @@ -0,0 +1,13 @@ +diff --git a/chipsec/helper/linux/linuxhelper.py b/chipsec/helper/linux/linuxhelper.py +index 2fd65140..f3f26bcb 100644 +--- a/chipsec/helper/linux/linuxhelper.py ++++ b/chipsec/helper/linux/linuxhelper.py +@@ -153,7 +153,7 @@ class LinuxHelper(Helper): + else: + a2 = f'a2=0x{phys_mem_access_prot}' + +- driver_path = os.path.join(chipsec.file.get_main_dir(), "chipsec", "helper", "linux", "chipsec.ko") ++ driver_path = os.path.join(chipsec.file.get_main_dir(), "drivers", "linux", "chipsec.ko") + if not os.path.exists(driver_path): + driver_path += ".xz" + if not os.path.exists(driver_path): \ No newline at end of file diff --git a/pkgs/default-tools/default.nix b/pkgs/default-tools/default.nix new file mode 100644 index 0000000..c432244 --- /dev/null +++ b/pkgs/default-tools/default.nix @@ -0,0 +1,38 @@ +{ lib +, fetchurl +, stdenv +, gzip +}: + +let + pname = "default-tools"; + version = "v2"; + sha256 = "sha256-8PTGQ4g3N/ZnfJ+bhRYGO94jsIf6T+WVFe6NtLiDZ+8="; +in + +stdenv.mkDerivation { + inherit pname version; + + src = fetchurl { + url = "https://fwci-assets.s3.eu-central-1.amazonaws.com/default-tools/default-tools-v2.tar.gz"; + inherit sha256; + }; + + nativeBuildInputs = [ gzip ]; + + # Extract the files to $out/ instead of $out/default-tools + installPhase = '' + mkdir -p $out + + # Extract directly from src to destination + gzip -dc $src > extracted.tar + tar -xf extracted.tar -C $out + + # Make all binaries executable + find $out -type f -exec chmod +x {} \; + ''; + + meta = with lib; { + description = "Default FirmwareCI tools package. These tools are required for some of the FirmwareCI teststeps."; + }; +} diff --git a/statix.toml b/statix.toml new file mode 100644 index 0000000..d769a29 --- /dev/null +++ b/statix.toml @@ -0,0 +1,4 @@ +disabled = [ + "manual_inherit", + "manual_inherit_from" +] \ No newline at end of file