Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
f86f964
Add native macOS CMake build support
gl-agnx Aug 12, 2026
9fb0edc
Add cross-platform build smoke CI
gl-agnx Aug 13, 2026
44adeba
Add Zynq boot image smoke tests
gl-agnx Aug 13, 2026
e709e57
Preserve UTF-8 and space-containing command paths
gl-agnx Aug 13, 2026
d4fa0fc
Support UTF-8 filenames in BIF files
gl-agnx Aug 14, 2026
0e0f238
Add opt-in parser regeneration target
gl-agnx Aug 14, 2026
0829cc2
Fix Versal 2VE/2VM hash block bounds
gl-agnx Aug 14, 2026
5ee28e2
Add cross-family boot image smoke tests
gl-agnx Aug 14, 2026
b138743
Test native Intel macOS builds in CI
gl-agnx Aug 15, 2026
baef138
Set the default macOS deployment target
gl-agnx Aug 15, 2026
1d873b8
Add macOS package validation
gl-agnx Aug 15, 2026
03cfd47
Add ZynqMP OpenSSL authentication smoke test
gl-agnx Aug 15, 2026
63e6009
Secure LMS key generation on POSIX hosts
gl-agnx Aug 15, 2026
23e76bd
Harden LMS signing file handling
gl-agnx Aug 16, 2026
0de374a
Use EVP for LMS SHA-256 hashing
gl-agnx Aug 17, 2026
c57dccf
Test incremental LMS hashing
gl-agnx Aug 17, 2026
7ea7a23
Add guarded universal macOS packaging workflow
gl-agnx Aug 17, 2026
5b04ba2
Include third-party notices in macOS packages
gl-agnx Aug 18, 2026
88be003
Test deterministic boot image generation
gl-agnx Aug 18, 2026
b42e483
Reject tampered authenticated ZynqMP images
gl-agnx Aug 18, 2026
cb9817c
Record native macOS port baseline
gl-agnx Aug 18, 2026
5a06bf8
Handle POSIX separators in split output names
gl-agnx Aug 18, 2026
85ecb93
Test split output paths from nested BIF files
gl-agnx Aug 18, 2026
8549a50
Document GitHub Actions contribution workflow
gl-agnx Aug 19, 2026
253e581
Use public OpenSSL APIs for ZynqMP RSA verification
gl-agnx Aug 19, 2026
560f266
Test authenticated Versal ECDSA images
gl-agnx Aug 20, 2026
be6238d
Use public OpenSSL APIs for Versal ECDSA keys
gl-agnx Aug 20, 2026
3d5fae3
Preserve Versal key ownership during copies
gl-agnx Aug 21, 2026
79e827d
Preserve sibling-family key ownership during copies
gl-agnx Aug 21, 2026
71fd0a8
Test authenticated Spartan UltraScale+ image builds
gl-agnx Aug 21, 2026
fc74f5e
Use public OpenSSL APIs for Spartan ECDSA keys
gl-agnx Aug 21, 2026
cfd659f
Remove 2VE/2VM internal debug output
gl-agnx Aug 21, 2026
2ecc58f
Test authenticated Versal 2VE/2VM image builds
gl-agnx Aug 22, 2026
64c324a
Use public OpenSSL APIs for 2VE/2VM ECDSA keys
gl-agnx Aug 22, 2026
8563ece
Remove OpenSSL BIGNUM structure dependency
gl-agnx Aug 23, 2026
91d2aa6
Document release validation evidence
gl-agnx Aug 24, 2026
93cdd8a
Require a supported OpenSSL version
gl-agnx Aug 24, 2026
c604c7b
Reject truncated boot images in all readers
gl-agnx Aug 24, 2026
9fa7c62
Detect malformed image reader crashes
gl-agnx Aug 24, 2026
f4aa8d5
Enable CDO buffer loading on macOS
gl-agnx Aug 24, 2026
a19f1d1
Record upstream macOS proposal audit
gl-agnx Aug 24, 2026
8164597
Harden Versal CDO partition decoding
gl-agnx Aug 24, 2026
f24a444
Harden encrypted CDO decoding in sibling families
gl-agnx Aug 24, 2026
d3ef97e
Document signing macOS packages before CPack
gl-agnx Aug 25, 2026
c3af7cd
Fix macOS package signing documentation formatting
gl-agnx Aug 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 106 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
name: Build and test

on:
push:
pull_request:
workflow_dispatch:

permissions:
contents: read

jobs:
build:
name: ${{ matrix.name }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- name: Ubuntu GCC
os: ubuntu-24.04
cc: gcc
cxx: g++
cmake_options: ''
- name: Ubuntu Clang
os: ubuntu-24.04
cc: clang
cxx: clang++
cmake_options: ''
- name: Ubuntu Clang sanitizers
os: ubuntu-24.04
cc: clang
cxx: clang++
cmake_options: -DBOOTGEN_ENABLE_SANITIZERS=ON
- name: macOS Apple Silicon
os: macos-15
cc: clang
cxx: clang++
cmake_options: -DCMAKE_OSX_ARCHITECTURES=arm64
- name: macOS Intel
os: macos-15-intel
cc: clang
cxx: clang++
cmake_options: -DCMAKE_OSX_ARCHITECTURES=x86_64

defaults:
run:
shell: bash

env:
CC: ${{ matrix.cc }}
CXX: ${{ matrix.cxx }}
CMAKE_OPTIONS: ${{ matrix.cmake_options }}

steps:
- uses: actions/checkout@v4

- name: Install Linux dependencies
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install --yes ninja-build libssl-dev

- name: Install macOS dependencies
if: runner.os == 'macOS'
run: |
brew install ninja openssl@3
echo "OPENSSL_ROOT_DIR=$(brew --prefix openssl@3)" >> "$GITHUB_ENV"

- name: Configure
run: |
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release \
${OPENSSL_ROOT_DIR:+-DOPENSSL_ROOT_DIR="$OPENSSL_ROOT_DIR"} \
${CMAKE_OPTIONS:-}

- name: Build
run: cmake --build build --parallel

- name: Test
run: ctest --test-dir build --output-on-failure --output-junit build/ctest.xml

- name: Confirm macOS binary architecture
if: runner.os == 'macOS'
run: |
file build/bootgen
if [[ "${{ matrix.name }}" == "macOS Apple Silicon" ]]; then
file build/bootgen | grep -q 'arm64'
else
file build/bootgen | grep -q 'x86_64'
fi

- name: Package macOS tarball
if: runner.os == 'macOS'
run: cmake --build build --target package

- name: Upload artifacts
if: always()
uses: actions/upload-artifact@v4
with:
name: bootgen-${{ matrix.name }}
if-no-files-found: error
path: |
build/bootgen
build/ctest.xml
build/*.tar.gz
LICENSE
BUILDING.md
161 changes: 161 additions & 0 deletions BUILDING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
# Building Bootgen

Bootgen's CMake build supports native Linux and macOS hosts. It uses checked-in
Bison and Flex output, so parser generators are not required for a normal
build.

## Requirements

- A C++14 compiler
- CMake 3.20 or newer
- OpenSSL 1.1.1 or newer development headers and libraries (OpenSSL 3 on macOS)
- A threading implementation supported by CMake

On macOS, install the build prerequisites with Homebrew:

```sh
brew install cmake ninja openssl@3
```

## CMake build

Configure with the normal CMake OpenSSL hint when the dependency is not in a
default search path. The path is deliberately supplied by the caller; Bootgen
does not embed Homebrew installation paths.

```sh
cmake -S . -B build/macos-arm64 -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_OSX_ARCHITECTURES=arm64 \
-DOPENSSL_ROOT_DIR="$(brew --prefix openssl@3)"
cmake --build build/macos-arm64 --parallel
ctest --test-dir build/macos-arm64 --output-on-failure
```

CMake defaults macOS builds to deployment target 15.0, matching the native
macOS CI runners. Override
`CMAKE_OSX_DEPLOYMENT_TARGET` only when all dependencies, including OpenSSL,
support the selected target.

For an Intel build, run the same configuration on an Intel Mac and set
`CMAKE_OSX_ARCHITECTURES=x86_64`. Test each architecture before any universal
binary packaging. Assemble separately tested slices with the checked
compatibility workflow:

```sh
cmake \
-DSOURCE_DIR="$PWD" \
-DARM64_BINARY="$PWD/build/macos-arm64/bootgen" \
-DX86_64_BINARY="$PWD/build/macos-x86_64/bootgen" \
-DOUTPUT_DIR="$PWD/build/universal" \
-P cmake/package_universal_macos.cmake
file build/universal/bootgen-universal/bin/bootgen
codesign --force --sign - build/universal/bootgen-universal/bin/bootgen
codesign --verify --deep --strict build/universal/bootgen-universal/bin/bootgen
```

The script verifies both executable slices, requires their `otool -L` runtime
dependencies to match, and checks non-system absolute dependencies (including
OpenSSL) are themselves universal. The resulting staging tree includes the
binary, license, and build documentation.

Install into a staging directory with:

```sh
cmake --install build/macos-arm64 --prefix "$PWD/stage"
```

## macOS packaging and runtime dependencies

The CMake `package` target creates an architecture-specific tarball containing
`bootgen`, its license notices, and build documentation. Sign the executable
before invoking CPack so the signed Mach-O is the one installed into the
tarball:

```sh
file build/macos-arm64/bootgen
otool -L build/macos-arm64/bootgen
codesign --force --sign - build/macos-arm64/bootgen
codesign --verify --deep --strict build/macos-arm64/bootgen
cmake --build build/macos-arm64 --target package
```

For a release, replace `-` with the intended Developer ID identity. Verify the
artifact itself after extracting it; a signature applied after packaging does
not modify an existing tarball:

```sh
PACKAGE_DIR="$(mktemp -d)"
tar -xzf build/macos-arm64/bootgen-*-Darwin-arm64.tar.gz -C "$PACKAGE_DIR"
codesign --verify --deep --strict "$PACKAGE_DIR"/bootgen-*/bin/bootgen
```

Bootgen intentionally links to the caller-supplied OpenSSL installation; the
tarball does not bundle or sign OpenSSL. Install the matching-architecture
Homebrew `openssl@3` package before running it.

See `THIRD_PARTY_NOTICES.md` for the source and binary distribution inventory.
The package includes Bootgen's aggregate `LICENSE` and the separate Cisco
BSD-3-Clause notice for the LMS/HSS implementation. OpenSSL remains a dynamic,
caller-supplied dependency and is not redistributed in the package.

Ad-hoc signing is appropriate for local development. A released universal
package requires compatible universal OpenSSL libraries; it must not merge
executables against incompatible runtime libraries.

The compatibility Makefile provides a `macos` target that delegates to CMake:

```sh
make macos CMAKE_ARGS="-DOPENSSL_ROOT_DIR=$(brew --prefix openssl@3)"
```

## Sanitizers

Use the following configuration for the initial host smoke tests:

```sh
cmake -S . -B build/macos-asan -G Ninja \
-DBOOTGEN_ENABLE_SANITIZERS=ON \
-DOPENSSL_ROOT_DIR="$(brew --prefix openssl@3)"
cmake --build build/macos-asan --parallel
ctest --test-dir build/macos-asan --output-on-failure
```

## Release validation matrix

A successful local build proves only the host and dependency architecture used
for that build. Before publishing a macOS binary or proposing these changes
upstream, run and retain the results of the following checks:

| Gate | Required evidence |
| --- | --- |
| Apple Silicon | Native `arm64` release and sanitizer builds with the complete CTest suite. |
| Intel macOS | Native `x86_64` release and sanitizer builds with the complete CTest suite and Intel Homebrew OpenSSL. |
| Universal package | Independently tested arm64 and x86_64 binaries, universal compatible OpenSSL dependencies, and a successful `package_universal_macos.cmake` run. |
| Linux compatibility | GCC, Clang, and sanitizer builds using the project workflow or an equivalent native Linux environment. |
| Image compatibility | Comparisons with a pinned upstream reference for deterministic images; structural and signature verification for randomized authenticated images. |
| Hosted CI | A clean GitHub Actions run from the contributor fork for every matrix job. |

The current GitHub workflow covers the Linux compiler/sanitizer and native macOS
architecture jobs after the branch is pushed to a fork. It intentionally does
not synthesize a universal package from untested slices.

## Parser regeneration (maintainers only)

The `bisonflex` directory is checked in. Regenerate it only when changing a
grammar or lexer, using Bison 2.7 or newer and Flex 2.5.35 or newer. This is an
explicit opt-in target because generator upgrades can create large reviewable
diffs.

```sh
cmake -S . -B build/parser-maintenance -DBOOTGEN_REGENERATE_PARSERS=ON
cmake --build build/parser-maintenance --target regenerate-parsers
```

The target updates checked-in files in `bisonflex`; inspect those changes,
rebuild, and run the complete test suite before committing them. Normal CMake
and Make builds do not configure or invoke parser generators.

Sanitizer coverage and the current smoke test do not establish boot-image
compatibility. Golden-image, cryptographic, malformed-input, and hardware
tests remain required before a release-quality macOS port can be claimed.
Loading