Example project for using a FIPs Ready linux image on qemu and on RPI 5 with an initramfs kernel module loading, and ported projects to utilize wolfCrypt throughout the image example
parent
bee7a18993
commit
28fcdbbc24
|
|
@ -0,0 +1,38 @@
|
|||
# Cloned repos (pulled by setup.sh, symlinked into layers/)
|
||||
repos/
|
||||
|
||||
# Symlinks in layers/ pointing to repos/ (recreated by setup.sh)
|
||||
layers/poky
|
||||
layers/meta-raspberrypi
|
||||
layers/meta-openembedded
|
||||
layers/meta-wolfssl
|
||||
|
||||
# FIPS Ready config (contains bundle-specific details)
|
||||
conf/wolfssl-fips-ready.conf
|
||||
|
||||
# Build artifacts
|
||||
build/
|
||||
downloads/
|
||||
sstate-cache/
|
||||
|
||||
# Images copied by make move-image
|
||||
*.wic
|
||||
*.wic.bz2
|
||||
*.wic.gz
|
||||
*.wic.bmap
|
||||
|
||||
# FIPS Ready bundle (commercial, do not commit)
|
||||
*.zip
|
||||
|
||||
# Generated network config (created by make ip-* / set-network.sh)
|
||||
layers/meta-network-overrides/recipes-core/network-config/files/20-wired.network
|
||||
|
||||
# direnv (generated by setup.sh)
|
||||
.envrc
|
||||
|
||||
# Project root is not a layer (old locations)
|
||||
/conf/layer.conf
|
||||
/recipes-core/
|
||||
|
||||
# Claude Code memory (local only)
|
||||
memory/
|
||||
|
|
@ -0,0 +1,268 @@
|
|||
# Makefile - Yocto Scarthgap RPi5 build targets
|
||||
#
|
||||
# Usage:
|
||||
# ./setup.sh - clone layers and check host tools
|
||||
# make configure - initialize build dir and write config
|
||||
# make build - build the image
|
||||
|
||||
SHELL := /bin/bash
|
||||
TOPDIR := $(shell pwd)
|
||||
BUILD_DIR := $(TOPDIR)/build
|
||||
POKY_DIR := $(TOPDIR)/layers/poky
|
||||
FIPS_IMAGE := wolfssl-fips-ready-image
|
||||
BASE_IMAGE := core-image-base
|
||||
MACHINE := raspberrypi5
|
||||
DEPLOY_DIR := $(BUILD_DIR)/tmp/deploy/images/$(MACHINE)
|
||||
QEMU_MACHINE := qemuarm64
|
||||
QEMU_IMAGE := wolfssl-fips-ready-image-qemu
|
||||
QEMU_CONF := $(TOPDIR)/conf/qemu-override.conf
|
||||
QEMU_DEPLOY_DIR := $(BUILD_DIR)/tmp/deploy/images/$(QEMU_MACHINE)
|
||||
|
||||
# Helper: source the OE environment and run a bitbake command
|
||||
define bitbake-cmd
|
||||
@if [ ! -d "$(POKY_DIR)" ]; then \
|
||||
echo "Error: poky not found. Run ./setup.sh first."; \
|
||||
exit 1; \
|
||||
fi
|
||||
@source $(POKY_DIR)/oe-init-build-env $(BUILD_DIR) > /dev/null 2>&1 && $(1)
|
||||
endef
|
||||
|
||||
LAYERS_DIR := $(TOPDIR)/layers
|
||||
OVERRIDES_LAYER := $(LAYERS_DIR)/meta-wolfssl-overrides
|
||||
BBLAYERS_CONF := $(BUILD_DIR)/conf/bblayers.conf
|
||||
LOCAL_CONF := $(BUILD_DIR)/conf/local.conf
|
||||
FIPS_CONF := $(TOPDIR)/conf/wolfssl-fips-ready.conf
|
||||
FIPS_MARKER := \# ==== wolfssl-fips-ready config ====
|
||||
|
||||
.PHONY: configure build build-minimal clean distclean clean-project image-info move-image ip-dhcp fips-on fips-off fips-status qemu run-qemu shell help
|
||||
|
||||
## configure: Initialize build dir, write bblayers.conf and local.conf
|
||||
configure:
|
||||
@$(TOPDIR)/configure.sh
|
||||
|
||||
## build: Build the image (FIPS image if enabled, base image otherwise)
|
||||
build:
|
||||
@if [ -f "$(BBLAYERS_CONF)" ] && grep -q "meta-wolfssl-overrides" "$(BBLAYERS_CONF)" 2>/dev/null; then \
|
||||
echo "FIPS enabled - building $(FIPS_IMAGE)"; \
|
||||
else \
|
||||
echo "Building $(BASE_IMAGE)"; \
|
||||
fi
|
||||
$(call bitbake-cmd, \
|
||||
if grep -q "meta-wolfssl-overrides" "$(BBLAYERS_CONF)" 2>/dev/null; then \
|
||||
bitbake $(FIPS_IMAGE); \
|
||||
else \
|
||||
bitbake $(BASE_IMAGE); \
|
||||
fi)
|
||||
|
||||
## build-minimal: Build core-image-minimal for RPi5
|
||||
build-minimal:
|
||||
$(call bitbake-cmd, bitbake core-image-minimal)
|
||||
|
||||
## clean: Clean the active image sstate (cleansstate)
|
||||
clean:
|
||||
$(call bitbake-cmd, \
|
||||
if grep -q "meta-wolfssl-overrides" "$(BBLAYERS_CONF)" 2>/dev/null; then \
|
||||
bitbake -c cleansstate $(FIPS_IMAGE); \
|
||||
else \
|
||||
bitbake -c cleansstate $(BASE_IMAGE); \
|
||||
fi)
|
||||
|
||||
## distclean: Remove the entire build directory
|
||||
distclean:
|
||||
@echo "Removing build directory: $(BUILD_DIR)"
|
||||
rm -rf $(BUILD_DIR)
|
||||
|
||||
## clean-project: Reset to clean state (keeps source files and FIPS bundle)
|
||||
clean-project:
|
||||
@echo "Removing all generated files and caches..."
|
||||
rm -rf $(BUILD_DIR) $(TOPDIR)/repos $(TOPDIR)/downloads $(TOPDIR)/sstate-cache
|
||||
rm -rf $(TOPDIR)/conf/wolfssl-fips-ready.conf $(TOPDIR)/.envrc
|
||||
rm -f $(TOPDIR)/*.wic $(TOPDIR)/*.wic.bz2 $(TOPDIR)/*.wic.gz $(TOPDIR)/*.wic.bmap
|
||||
rm -f $(TOPDIR)/layers/meta-network-overrides/recipes-core/network-config/files/20-wired.network
|
||||
@echo "Done. Run './setup.sh' to start fresh."
|
||||
|
||||
## image-info: Show the output image location and file sizes
|
||||
image-info:
|
||||
@echo "Deploy directory: $(DEPLOY_DIR)"
|
||||
@echo ""
|
||||
@if [ -d "$(DEPLOY_DIR)" ]; then \
|
||||
ls -lh $(DEPLOY_DIR)/*.wic.bz2 2>/dev/null || \
|
||||
ls -lh $(DEPLOY_DIR)/*.wic.gz 2>/dev/null || \
|
||||
ls -lh $(DEPLOY_DIR)/*.wic 2>/dev/null || \
|
||||
echo "No .wic image found yet. Run 'make build' first."; \
|
||||
else \
|
||||
echo "Deploy directory does not exist. Run 'make build' first."; \
|
||||
fi
|
||||
|
||||
## move-image: Copy the latest .wic image to the current directory
|
||||
move-image:
|
||||
@LATEST=$$(ls -t $(DEPLOY_DIR)/*.wic.bz2 2>/dev/null | head -1); \
|
||||
if [ -z "$$LATEST" ]; then \
|
||||
LATEST=$$(ls -t $(DEPLOY_DIR)/*.wic.gz 2>/dev/null | head -1); \
|
||||
fi; \
|
||||
if [ -z "$$LATEST" ]; then \
|
||||
LATEST=$$(ls -t $(DEPLOY_DIR)/*.wic 2>/dev/null | head -1); \
|
||||
fi; \
|
||||
if [ -z "$$LATEST" ]; then \
|
||||
echo "No .wic image found. Run 'make build' first."; \
|
||||
exit 1; \
|
||||
fi; \
|
||||
echo "Copying $$LATEST to ."; \
|
||||
cp "$$LATEST" . ; \
|
||||
echo "Done: $$(basename $$LATEST)"
|
||||
|
||||
## generate-fips-conf: Generate wolfssl-fips-ready.conf from a bundle .zip
|
||||
## Usage: make generate-fips-conf BUNDLE=/path/to/wolfssl-x.x.x-gplv3-fips-ready.zip
|
||||
generate-fips-conf:
|
||||
@if [ -z "$(BUNDLE)" ]; then \
|
||||
echo "Usage: make generate-fips-conf BUNDLE=/path/to/wolfssl-x.x.x-gplv3-fips-ready.zip"; \
|
||||
exit 1; \
|
||||
fi
|
||||
@$(TOPDIR)/generate-fips-conf.sh "$(BUNDLE)"
|
||||
|
||||
## fips-on: Enable FIPS Ready - add overrides layer and require conf
|
||||
fips-on:
|
||||
@if [ ! -f "$(BBLAYERS_CONF)" ]; then \
|
||||
echo "Error: bblayers.conf not found. Run 'make configure' first."; \
|
||||
exit 1; \
|
||||
fi
|
||||
@if [ ! -f "$(FIPS_CONF)" ]; then \
|
||||
echo "Error: conf/wolfssl-fips-ready.conf not found."; \
|
||||
echo ""; \
|
||||
echo "Generate it from your bundle .zip:"; \
|
||||
echo " make generate-fips-conf BUNDLE=/path/to/wolfssl-x.x.x-gplv3-fips-ready.zip"; \
|
||||
echo ""; \
|
||||
echo "The bundle can live anywhere on disk."; \
|
||||
exit 1; \
|
||||
fi
|
||||
@# --- Add overrides layer to bblayers.conf ---
|
||||
@if grep -q "meta-wolfssl-overrides" "$(BBLAYERS_CONF)"; then \
|
||||
echo "[FIPS] Overrides layer already in bblayers.conf"; \
|
||||
else \
|
||||
sed -i 's|$(LAYERS_DIR)/meta-wolfssl \\|$(LAYERS_DIR)/meta-wolfssl \\\n $(OVERRIDES_LAYER) \\|' "$(BBLAYERS_CONF)"; \
|
||||
echo "[FIPS] Added overrides layer to bblayers.conf"; \
|
||||
fi
|
||||
@# --- Add FIPS config to local.conf ---
|
||||
@if grep -q "$(FIPS_MARKER)" "$(LOCAL_CONF)"; then \
|
||||
echo "[FIPS] FIPS config block already in local.conf"; \
|
||||
else \
|
||||
echo '' >> "$(LOCAL_CONF)"; \
|
||||
echo '$(FIPS_MARKER)' >> "$(LOCAL_CONF)"; \
|
||||
echo 'require $(FIPS_CONF)' >> "$(LOCAL_CONF)"; \
|
||||
echo '' >> "$(LOCAL_CONF)"; \
|
||||
echo '# FIPS initramfs - kernel bundles wolfSSL kernel module for early boot' >> "$(LOCAL_CONF)"; \
|
||||
echo 'INITRAMFS_IMAGE = "core-image-minimal-initramfs"' >> "$(LOCAL_CONF)"; \
|
||||
echo 'INITRAMFS_IMAGE_BUNDLE = "1"' >> "$(LOCAL_CONF)"; \
|
||||
echo '$(FIPS_MARKER) END' >> "$(LOCAL_CONF)"; \
|
||||
echo "[FIPS] Added FIPS config to local.conf"; \
|
||||
fi
|
||||
@echo ""
|
||||
@echo "FIPS Ready ENABLED. Run 'make build' for the RPi5 image, or 'make qemu' for the QEMU image."
|
||||
|
||||
## fips-off: Disable FIPS Ready - remove overrides layer and FIPS config
|
||||
fips-off:
|
||||
@if [ ! -f "$(BBLAYERS_CONF)" ]; then \
|
||||
echo "Error: bblayers.conf not found. Run 'make configure' first."; \
|
||||
exit 1; \
|
||||
fi
|
||||
@# --- Remove overrides layer from bblayers.conf ---
|
||||
@if grep -q "meta-wolfssl-overrides" "$(BBLAYERS_CONF)"; then \
|
||||
sed -i '\|meta-wolfssl-overrides|d' "$(BBLAYERS_CONF)"; \
|
||||
echo "[FIPS] Removed overrides layer from bblayers.conf"; \
|
||||
else \
|
||||
echo "[FIPS] Overrides layer already removed from bblayers.conf"; \
|
||||
fi
|
||||
@# --- Remove FIPS config block from local.conf ---
|
||||
@if grep -q "$(FIPS_MARKER)" "$(LOCAL_CONF)"; then \
|
||||
sed -i '/^$(FIPS_MARKER)/,/^$(FIPS_MARKER) END/d' "$(LOCAL_CONF)"; \
|
||||
echo "[FIPS] Removed FIPS config block from local.conf"; \
|
||||
else \
|
||||
echo "[FIPS] FIPS config block already removed from local.conf"; \
|
||||
fi
|
||||
@echo ""
|
||||
@echo "FIPS Ready DISABLED. Run 'make clean && make build' to rebuild."
|
||||
|
||||
## fips-status: Show whether FIPS Ready overrides are enabled
|
||||
fips-status:
|
||||
@if [ ! -f "$(BBLAYERS_CONF)" ]; then \
|
||||
echo "FIPS: unknown (bblayers.conf not found)"; \
|
||||
elif grep -q "meta-wolfssl-overrides" "$(BBLAYERS_CONF)"; then \
|
||||
echo "FIPS: ENABLED"; \
|
||||
if [ -f "$(FIPS_CONF)" ]; then \
|
||||
echo "Config: conf/wolfssl-fips-ready.conf found"; \
|
||||
else \
|
||||
echo "Config: conf/wolfssl-fips-ready.conf MISSING"; \
|
||||
fi; \
|
||||
else \
|
||||
echo "FIPS: DISABLED"; \
|
||||
fi
|
||||
|
||||
## ip-dhcp: Set network to DHCP
|
||||
ip-dhcp:
|
||||
@$(TOPDIR)/set-network.sh dhcp
|
||||
|
||||
## ip-<address>: Set static IP (e.g. make ip-192.168.1.100)
|
||||
## Optional: GW=192.168.1.1 PREFIX=24 DNS=8.8.8.8
|
||||
ip-%:
|
||||
@$(TOPDIR)/set-network.sh static $* $(GW) $(PREFIX) $(DNS)
|
||||
|
||||
## qemu: Build the FIPS Ready image for QEMU (aarch64)
|
||||
qemu:
|
||||
@if [ ! -f "$(BBLAYERS_CONF)" ]; then \
|
||||
echo "Error: bblayers.conf not found. Run 'make configure' first."; \
|
||||
exit 1; \
|
||||
fi
|
||||
@if ! grep -q "meta-wolfssl-overrides" "$(BBLAYERS_CONF)" 2>/dev/null; then \
|
||||
echo "Error: FIPS not enabled. Run 'make fips-on' first."; \
|
||||
exit 1; \
|
||||
fi
|
||||
@echo "Building $(QEMU_IMAGE) for $(QEMU_MACHINE)"
|
||||
$(call bitbake-cmd, bitbake -R $(QEMU_CONF) $(QEMU_IMAGE))
|
||||
|
||||
## run-qemu: Launch the QEMU image (use QEMU_ARGS for extra options, e.g. QEMU_ARGS=nographic)
|
||||
run-qemu:
|
||||
@QBCONF=$$(ls -t $(QEMU_DEPLOY_DIR)/*.qemuboot.conf 2>/dev/null | head -1); \
|
||||
if [ -z "$$QBCONF" ]; then \
|
||||
echo "Error: No .qemuboot.conf found. Run 'make qemu' first."; \
|
||||
exit 1; \
|
||||
fi; \
|
||||
echo "Using: $$QBCONF"
|
||||
$(call bitbake-cmd, \
|
||||
QBCONF=$$(ls -t $(QEMU_DEPLOY_DIR)/*.qemuboot.conf 2>/dev/null | head -1) && \
|
||||
runqemu $$QBCONF nographic $(QEMU_ARGS))
|
||||
|
||||
## shell: Open an interactive shell with the bitbake environment sourced
|
||||
shell:
|
||||
@if [ ! -d "$(POKY_DIR)" ]; then \
|
||||
echo "Error: poky not found. Run ./setup.sh first."; \
|
||||
exit 1; \
|
||||
fi
|
||||
@echo "Entering bitbake environment shell. Type 'exit' to leave."
|
||||
@bash --init-file <(echo "source $(POKY_DIR)/oe-init-build-env $(BUILD_DIR)")
|
||||
|
||||
## help: Show available targets
|
||||
help:
|
||||
@echo "Yocto Scarthgap RPi5 Build Targets"
|
||||
@echo "==================================="
|
||||
@echo ""
|
||||
@echo " make configure - Initialize build dir and write config"
|
||||
@echo " make build - Build image for $(MACHINE) (FIPS or base, auto-detected)"
|
||||
@echo " make build-minimal - Build core-image-minimal for $(MACHINE)"
|
||||
@echo " make clean - Clean active image sstate"
|
||||
@echo " make distclean - Remove entire build directory"
|
||||
@echo " make clean-project - Reset to clean state (keeps source + bundle)"
|
||||
@echo " make image-info - Show output image location and sizes"
|
||||
@echo " make move-image - Copy latest .wic image to current directory"
|
||||
@echo " make generate-fips-conf BUNDLE=<path> - Generate FIPS config from .zip bundle"
|
||||
@echo " make fips-on - Enable FIPS Ready overrides"
|
||||
@echo " make fips-off - Disable FIPS overrides layer"
|
||||
@echo " make fips-status - Show FIPS override status"
|
||||
@echo " make qemu - Build FIPS Ready image for QEMU ($(QEMU_MACHINE))"
|
||||
@echo " make run-qemu - Launch QEMU image (nographic/headless by default)"
|
||||
@echo " make ip-dhcp - Set network to DHCP"
|
||||
@echo " make ip-<address> - Set static IP (e.g. make ip-192.168.1.100)"
|
||||
@echo " Optional: GW=x.x.x.x PREFIX=24 DNS=x.x.x.x"
|
||||
@echo " make shell - Open a bitbake-ready shell"
|
||||
@echo " make help - Show this help"
|
||||
@echo ""
|
||||
@echo "Run ./setup.sh first to clone layers and check host tools."
|
||||
|
|
@ -0,0 +1,635 @@
|
|||
# meta-wolfssl-linux-fips
|
||||
|
||||
Yocto Scarthgap build environment for Raspberry Pi 5 and QEMU (aarch64) with
|
||||
wolfSSL FIPS Ready cryptography.
|
||||
|
||||
## Overview
|
||||
|
||||
This project provides a turnkey setup for building a Linux image targeting the
|
||||
Raspberry Pi 5 or QEMU (aarch64) using the Yocto Project's **Scarthgap** (5.0)
|
||||
release. The RPi5 base image includes SSH, HDMI console output, Wi-Fi,
|
||||
Bluetooth, and systemd. The QEMU target allows testing the full FIPS Ready
|
||||
stack without physical hardware.
|
||||
|
||||
When FIPS is enabled, the image includes:
|
||||
|
||||
- **wolfSSL FIPS Ready** cryptographic library
|
||||
- **libgcrypt** with wolfSSL backend
|
||||
- **GnuTLS** with wolfSSL backend
|
||||
- **wolfProvider** (OpenSSL 3.x provider, replace-default mode)
|
||||
- **wolfSSL FIPS kernel module** loaded via initramfs at early boot
|
||||
- Kernel FIPS mode (`CONFIG_CRYPTO_FIPS=y`) and LKCAPI registration
|
||||
- wolfcrypttest, wolfcryptbenchmark, ptest suites for validation
|
||||
|
||||
## Prerequisites
|
||||
|
||||
### Host packages (Ubuntu/Debian)
|
||||
|
||||
```bash
|
||||
sudo apt install gawk wget git diffstat unzip texinfo gcc build-essential \
|
||||
chrpath socat cpio python3 python3-pip python3-pexpect xz-utils \
|
||||
debianutils iputils-ping python3-git python3-jinja2 python3-subunit \
|
||||
zstd liblz4-tool file locales libacl1
|
||||
sudo locale-gen en_US.UTF-8
|
||||
```
|
||||
|
||||
You can also run `./setup.sh` which will check for all required tools and
|
||||
report any that are missing. On non-Debian distros where the tool names differ,
|
||||
use `--ignore-missing-packages` to skip the check:
|
||||
|
||||
```bash
|
||||
./setup.sh --ignore-missing-packages
|
||||
```
|
||||
|
||||
### direnv (recommended)
|
||||
|
||||
direnv auto-sources the bitbake environment when you `cd` into the project
|
||||
directory. `setup.sh` generates the `.envrc` file automatically.
|
||||
|
||||
**Step 1 - Install direnv and add the shell hook (one-time, before running
|
||||
`setup.sh`):**
|
||||
|
||||
```bash
|
||||
sudo apt install -y direnv
|
||||
echo 'eval "$(direnv hook bash)"' >> ~/.bashrc
|
||||
```
|
||||
|
||||
Open a new terminal (or `exec bash`) so the hook is active. `source ~/.bashrc`
|
||||
is not sufficient in all shells.
|
||||
|
||||
**Step 2 - Run `./setup.sh`** (see Quick Start below). This generates the
|
||||
`.envrc` file. direnv will report it as blocked on the first run — that's
|
||||
expected.
|
||||
|
||||
**Step 3 - Allow direnv to load the generated `.envrc`:**
|
||||
|
||||
```bash
|
||||
direnv allow
|
||||
```
|
||||
|
||||
direnv will warn that `build/` isn't initialized yet — that's expected too.
|
||||
It clears once `make configure` runs.
|
||||
|
||||
**Step 4 - Run `make configure`.** direnv auto-sources the bitbake
|
||||
environment on the next prompt.
|
||||
|
||||
### System requirements
|
||||
|
||||
- **Disk space:** At least 65 GB free (downloads + sstate cache + build output)
|
||||
- **RAM:** 8 GB minimum, 16 GB+ recommended
|
||||
- **OS:** Linux (tested on Ubuntu 22.04+, Debian 13, WSL2)
|
||||
|
||||
## Quick Start
|
||||
|
||||
### 1. Common setup (required for all targets)
|
||||
|
||||
```bash
|
||||
# Clone required Yocto layers and check host tools
|
||||
./setup.sh
|
||||
|
||||
# Initialize build directory and write configuration
|
||||
make configure
|
||||
```
|
||||
|
||||
### 2a. RPi5 base image (no FIPS)
|
||||
|
||||
```bash
|
||||
# (Optional) Set a static IP - default is DHCP
|
||||
make ip-192.168.2.227 GW=192.168.2.1 PREFIX=24 DNS=8.8.8.8
|
||||
|
||||
# Build the base image
|
||||
make build
|
||||
|
||||
# Copy the image to the current directory for flashing
|
||||
make move-image
|
||||
```
|
||||
|
||||
### 2b. RPi5 FIPS Ready image
|
||||
|
||||
```bash
|
||||
# Generate FIPS config from your bundle (bundle can live anywhere on disk)
|
||||
make generate-fips-conf BUNDLE=/path/to/wolfssl-x.x.x-gplv3-fips-ready.zip
|
||||
|
||||
# Enable FIPS (adds overrides layer, initramfs, and FIPS conf to local.conf)
|
||||
make fips-on
|
||||
|
||||
# Build the FIPS image (auto-detected when FIPS is enabled)
|
||||
make build
|
||||
|
||||
# Copy and flash
|
||||
make move-image
|
||||
```
|
||||
|
||||
To disable FIPS and go back to the base image:
|
||||
|
||||
```bash
|
||||
make fips-off
|
||||
make build
|
||||
```
|
||||
|
||||
### 2c. QEMU FIPS Ready image (no RPi hardware needed)
|
||||
|
||||
This builds and runs the same FIPS Ready stack in QEMU, using `linux-yocto`
|
||||
(6.6) instead of `linux-raspberrypi`. The wolfSSL FIPS kernel module loads
|
||||
via initramfs at early boot, same as on RPi5.
|
||||
|
||||
```bash
|
||||
# Generate FIPS config and enable FIPS (if not already done)
|
||||
make generate-fips-conf BUNDLE=/path/to/wolfssl-x.x.x-gplv3-fips-ready.zip
|
||||
make fips-on
|
||||
|
||||
# Build the QEMU FIPS image
|
||||
make qemu
|
||||
|
||||
# Launch in QEMU (nographic/headless, serial on stdio)
|
||||
make run-qemu
|
||||
```
|
||||
|
||||
Exit QEMU with `Ctrl-A X`.
|
||||
|
||||
> **Note:** Both `make build` (RPi5) and `make qemu` (QEMU) can be used in
|
||||
> the same build directory. FIPS must be enabled (`make fips-on`) for both.
|
||||
> The `conf/qemu-override.conf` is applied via `bitbake -R` to swap the
|
||||
> machine and kernel without modifying `local.conf`.
|
||||
|
||||
## Build Targets
|
||||
|
||||
| Command | Description |
|
||||
|----------------------|----------------------------------------------|
|
||||
| `make configure` | Initialize build dir and write config |
|
||||
| `make build` | Build image (FIPS or base, auto-detected) |
|
||||
| `make build-minimal` | Build `core-image-minimal` for RPi5 |
|
||||
| `make clean` | Clean the active image (cleansstate) |
|
||||
| `make distclean` | Remove the entire build directory |
|
||||
| `make image-info` | Show output image location and size |
|
||||
| `make move-image` | Copy latest `.wic` image to current directory|
|
||||
| `make generate-fips-conf BUNDLE=<path>` | Generate FIPS config from .zip bundle |
|
||||
| `make fips-on` | Enable FIPS Ready overrides and initramfs |
|
||||
| `make fips-off` | Disable FIPS Ready overrides |
|
||||
| `make fips-status` | Show FIPS Ready status |
|
||||
| `make qemu` | Build FIPS Ready image for QEMU (qemuarm64) |
|
||||
| `make run-qemu` | Launch QEMU image (nographic by default) |
|
||||
| `make ip-dhcp` | Set network to DHCP |
|
||||
| `make ip-<address>` | Set static IP (e.g. `make ip-192.168.1.100`) |
|
||||
| `make shell` | Open a shell with the bitbake env sourced |
|
||||
|
||||
## FIPS Ready Architecture
|
||||
|
||||
When FIPS is enabled (`make fips-on`), the overrides layer
|
||||
(`layers/meta-wolfssl-overrides/`) is added to the build. This layer:
|
||||
|
||||
- Provides the `wolfssl-fips-ready-image` recipe for RPi5 and
|
||||
`wolfssl-fips-ready-image-qemu` for QEMU (both extend `core-image-base`)
|
||||
- Configures wolfSSL, libgcrypt, GnuTLS, wolfProvider, OpenSSL, curl, and
|
||||
OpenSSH via bbappends
|
||||
- Enables kernel FIPS mode and the wolfSSL kernel randomness patch
|
||||
- Bundles the wolfSSL FIPS kernel module into an initramfs for early boot
|
||||
- Signs the kernel module with the kernel's build key
|
||||
|
||||
### Boot sequence (FIPS enabled)
|
||||
|
||||
**RPi5:**
|
||||
```
|
||||
1. RPi5 firmware loads kernel (with bundled initramfs)
|
||||
2. Initramfs mounts, modprobe libwolfssl loads FIPS kernel module
|
||||
3. Root filesystem mounts
|
||||
4. Userspace applications use wolfSSL FIPS via:
|
||||
- wolfProvider (OpenSSL 3.x replace-default)
|
||||
- GnuTLS with wolfSSL backend
|
||||
- libgcrypt with wolfSSL backend
|
||||
```
|
||||
|
||||
**QEMU (qemuarm64):**
|
||||
```
|
||||
1. QEMU loads linux-yocto kernel (with bundled initramfs)
|
||||
2. Initramfs mounts, modprobe libwolfssl loads FIPS kernel module
|
||||
3. Root filesystem mounts (ext4 via virtio-blk)
|
||||
4. Same userspace FIPS stack as RPi5
|
||||
```
|
||||
|
||||
### FIPS bundle
|
||||
|
||||
The FIPS Ready bundle `.zip` can live anywhere on disk. Running
|
||||
`make generate-fips-conf BUNDLE=/path/to/bundle.zip` computes checksums and
|
||||
generates `conf/wolfssl-fips-ready.conf` pointing to the bundle's location.
|
||||
The bundle is never copied into the source tree.
|
||||
|
||||
## Network Configuration
|
||||
|
||||
The image uses systemd-networkd for network management. Set the IP configuration
|
||||
**before** building the image - it gets baked in.
|
||||
|
||||
### DHCP (default)
|
||||
|
||||
```bash
|
||||
make ip-dhcp
|
||||
make configure && make build
|
||||
```
|
||||
|
||||
### Static IP
|
||||
|
||||
```bash
|
||||
make ip-192.168.2.227 GW=192.168.2.1 PREFIX=24 DNS=8.8.8.8
|
||||
make configure && make build
|
||||
```
|
||||
|
||||
| Parameter | Default | Description |
|
||||
|-----------|--------------------------|--------------------------|
|
||||
| `GW` | Auto (IP with `.1`) | Gateway address |
|
||||
| `PREFIX` | `24` | Subnet prefix length |
|
||||
| `DNS` | `8.8.8.8` | DNS server |
|
||||
|
||||
## Flashing and Booting
|
||||
|
||||
### RPi5: Flash to SD card
|
||||
|
||||
```bash
|
||||
make move-image
|
||||
lsblk # find your SD card device
|
||||
|
||||
# Using bmaptool (recommended)
|
||||
sudo bmaptool copy wolfssl-fips-ready-image-raspberrypi5.rootfs.wic.bz2 /dev/sdX
|
||||
|
||||
# Using dd
|
||||
bzcat wolfssl-fips-ready-image-raspberrypi5.rootfs.wic.bz2 | sudo dd of=/dev/sdX bs=4M status=progress
|
||||
```
|
||||
|
||||
### RPi5: Boot and connect
|
||||
|
||||
**Login:** `root` with no password (`debug-tweaks` is enabled).
|
||||
|
||||
**SSH:**
|
||||
```bash
|
||||
ssh root@192.168.2.227
|
||||
```
|
||||
|
||||
### QEMU: Launch and connect
|
||||
|
||||
```bash
|
||||
make run-qemu
|
||||
```
|
||||
|
||||
Boots directly to a login prompt on stdio. Login as `root` (no password).
|
||||
Exit with `Ctrl-A X`.
|
||||
|
||||
## Testing
|
||||
|
||||
These tests apply to both RPi5 and QEMU. Run them after booting the image.
|
||||
|
||||
### 1. Kernel Module Verification
|
||||
|
||||
Verify that the wolfSSL FIPS kernel module loaded via initramfs:
|
||||
|
||||
```bash
|
||||
lsmod | grep libwolfssl
|
||||
dmesg | grep -i wolfssl
|
||||
```
|
||||
|
||||
Expected dmesg output includes:
|
||||
```
|
||||
FIPS 140-3 wolfCrypt-fips ... startup self-test succeeded.
|
||||
wolfCrypt self-test passed.
|
||||
wolfCrypt: changing fips_enabled from 0 to 1 for FIPS module.
|
||||
```
|
||||
|
||||
Followed by LKCAPI algorithm registrations (AES-CBC, AES-GCM, HMAC-SHA*, SHA*, RSA, ECDSA, ECDH, DRBG).
|
||||
|
||||
Verify kernel crypto API registration:
|
||||
```bash
|
||||
cat /proc/crypto | grep -A 5 wolfcrypt
|
||||
```
|
||||
|
||||
### 2. Kernel Randomness
|
||||
|
||||
If the kernel randomness patch is applied, verify the wolfSSL DRBG is integrated:
|
||||
|
||||
```bash
|
||||
dmesg | grep "kernel global random_bytes handlers installed"
|
||||
```
|
||||
|
||||
Test the DRBG under load:
|
||||
```bash
|
||||
# Basic test (2 GB)
|
||||
dd if=/dev/urandom bs=1M count=2000 status=progress of=/dev/null
|
||||
```
|
||||
|
||||
### 3. Cryptographic Benchmarking
|
||||
|
||||
Test kernel crypto via cryptsetup:
|
||||
|
||||
```bash
|
||||
cryptsetup benchmark --cipher aes-cbc --key-size 256
|
||||
cryptsetup benchmark
|
||||
```
|
||||
|
||||
### 4. wolfCrypt Tests
|
||||
|
||||
```bash
|
||||
wolfcrypttest
|
||||
wolfcryptbenchmark
|
||||
```
|
||||
|
||||
### 5. Testing libgcrypt
|
||||
|
||||
libgcrypt is configured to use wolfSSL as its crypto backend.
|
||||
|
||||
```bash
|
||||
ptest-runner libgcrypt
|
||||
```
|
||||
|
||||
Expected output: all tests PASS (basic, mpitests, curves, fips186-dsa, etc.).
|
||||
|
||||
Verify library linking:
|
||||
```bash
|
||||
ldd /usr/lib/libgcrypt.so.20 # should show libwolfssl
|
||||
```
|
||||
|
||||
### 6. Testing GnuTLS
|
||||
|
||||
GnuTLS uses wolfSSL via the wolfssl-gnutls-wrapper.
|
||||
|
||||
```bash
|
||||
cd /opt/wolfssl-gnutls-wrapper/tests/
|
||||
make run_fips
|
||||
```
|
||||
|
||||
All tests should pass with wrapper log messages showing crypto operations routed to wolfSSL.
|
||||
|
||||
Verify wrapper linking:
|
||||
```bash
|
||||
ldd /opt/wolfssl-gnutls-wrapper/lib/libgnutls-wolfssl-wrapper.so
|
||||
# should show both libgnutls.so and libwolfssl.so
|
||||
```
|
||||
|
||||
### 7. Testing wolfProvider
|
||||
|
||||
wolfProvider is an OpenSSL 3.x provider using wolfSSL as the crypto backend, configured in replace-default mode.
|
||||
|
||||
```bash
|
||||
wolfprovidertest
|
||||
```
|
||||
|
||||
Expected output:
|
||||
```
|
||||
Setting up environment...
|
||||
Detected replace-default mode (from config file)
|
||||
Detected wolfSSL FIPS build (from config file)
|
||||
...
|
||||
###### TESTSUITE SUCCESS
|
||||
==========================================
|
||||
Unit tests PASSED!
|
||||
==========================================
|
||||
```
|
||||
|
||||
### 8. Testing libssh (via libgcrypt)
|
||||
|
||||
```bash
|
||||
ptest-runner libssh
|
||||
```
|
||||
|
||||
Some tests may fail due to MD5 not being available in FIPS mode. Expected failures:
|
||||
- `torture_keyfiles` - legacy key formats using MD5
|
||||
- `torture_pki_rsa` - legacy RSA key formats using MD5
|
||||
- `torture_threads_pki_rsa` - multi-threaded legacy RSA using MD5
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
meta-wolfssl-linux-fips/
|
||||
├── README.md
|
||||
├── .gitignore
|
||||
├── .envrc # (generated by setup.sh) direnv config
|
||||
├── setup.sh # Clone repos, create symlinks, check host tools
|
||||
├── configure.sh # Initialize build dir and write config
|
||||
├── generate-fips-conf.sh # Generate FIPS config from bundle .zip
|
||||
├── set-network.sh # Write network config (called by make ip-*)
|
||||
├── Makefile # Build/clean/utility targets
|
||||
├── conf/
|
||||
│ ├── wolfssl-fips-ready.conf # (generated) FIPS bundle config
|
||||
│ └── qemu-override.conf # QEMU machine overrides for bitbake -R
|
||||
├── layers/
|
||||
│ ├── poky -> ../repos/poky # (symlink)
|
||||
│ ├── meta-raspberrypi -> ../repos/meta-raspberrypi # (symlink)
|
||||
│ ├── meta-openembedded -> ../repos/meta-openembedded # (symlink)
|
||||
│ ├── meta-wolfssl -> ../repos/meta-wolfssl # (symlink)
|
||||
│ └── meta-wolfssl-overrides/ # FIPS overrides layer (tracked)
|
||||
│ ├── conf/layer.conf
|
||||
│ ├── recipes-core/images/
|
||||
│ │ ├── wolfssl-fips-ready-image.bb # RPi5 FIPS image
|
||||
│ │ ├── wolfssl-fips-ready-image-qemu.bb # QEMU FIPS image
|
||||
│ │ └── core-image-minimal-initramfs.bbappend
|
||||
│ ├── recipes-kernel/linux/
|
||||
│ │ ├── linux-raspberrypi_%.bbappend # RPi kernel patches
|
||||
│ │ ├── linux-yocto_%.bbappend # QEMU kernel patches
|
||||
│ │ └── files/fips-crypto.cfg
|
||||
│ ├── recipes-wolfssl/
|
||||
│ │ ├── wolfssl/wolfssl-fips-ready.bbappend
|
||||
│ │ ├── wolfssl/wolfssl-linuxkm-fips-ready.bbappend
|
||||
│ │ └── wolfprovider/wolfprovider_%.bbappend
|
||||
│ ├── recipes-support/
|
||||
│ │ ├── curl/curl_%.bbappend
|
||||
│ │ ├── gnupg/gnupg_%.bbappend
|
||||
│ │ ├── gnutls/gnutls_%.bbappend
|
||||
│ │ ├── libgcrypt/libgcrypt_%.bbappend
|
||||
│ │ └── nettle/nettle_%.bbappend
|
||||
│ ├── recipes-connectivity/
|
||||
│ │ ├── openssh/openssh_%.bbappend
|
||||
│ │ └── openssl/openssl_%.bbappend
|
||||
│ └── recipes-core/network-config/ # Network config recipe
|
||||
│ ├── network-config_1.0.bb
|
||||
│ └── files/20-wired.network # (generated by make ip-*)
|
||||
├── repos/ # Cloned git repos (git-ignored)
|
||||
├── build/ # Build directory (git-ignored)
|
||||
├── downloads/ # Shared download cache (git-ignored)
|
||||
└── sstate-cache/ # Shared state cache (git-ignored)
|
||||
```
|
||||
|
||||
## Image Configuration
|
||||
|
||||
### RPi5
|
||||
|
||||
| Setting | Value |
|
||||
|-------------|--------------------------------------|
|
||||
| Machine | `raspberrypi5` |
|
||||
| Kernel | `linux-raspberrypi` (6.6) |
|
||||
| Base image | `core-image-base` |
|
||||
| FIPS image | `wolfssl-fips-ready-image` |
|
||||
| SSH | OpenSSH server enabled |
|
||||
| Display | vc4graphics / HDMI 1080p |
|
||||
| Wi-Fi | Enabled (linux-firmware-rpidistro) |
|
||||
| Bluetooth | Enabled (bluez5) |
|
||||
| Init system | systemd |
|
||||
| U-Boot | Disabled (direct kernel boot) |
|
||||
| Login | `root` / no password (debug-tweaks) |
|
||||
| Branch | Scarthgap (Yocto 5.0) |
|
||||
|
||||
### QEMU (aarch64)
|
||||
|
||||
| Setting | Value |
|
||||
|-------------|--------------------------------------|
|
||||
| Machine | `qemuarm64` |
|
||||
| Kernel | `linux-yocto` (6.6) |
|
||||
| FIPS image | `wolfssl-fips-ready-image-qemu` |
|
||||
| CPU | `-cpu max` (supports A76 binaries) |
|
||||
| Console | nographic (serial on stdio) |
|
||||
| Networking | TAP via virtio-net-pci |
|
||||
| Init system | systemd |
|
||||
| Login | `root` / no password (debug-tweaks) |
|
||||
| Branch | Scarthgap (Yocto 5.0) |
|
||||
|
||||
## What Each Step Does (Manual Equivalent)
|
||||
|
||||
If you want to integrate wolfSSL FIPS Ready into your own Yocto project, here
|
||||
is what each make target does under the hood and the equivalent manual steps.
|
||||
|
||||
### `./setup.sh`
|
||||
|
||||
Clones the required Yocto layers into `repos/` and creates symlinks in
|
||||
`layers/` so `bblayers.conf` has a single directory to reference:
|
||||
|
||||
```bash
|
||||
git clone -b scarthgap git://git.yoctoproject.org/poky repos/poky
|
||||
git clone -b scarthgap git://git.yoctoproject.org/meta-raspberrypi repos/meta-raspberrypi
|
||||
git clone -b scarthgap git://git.openembedded.org/meta-openembedded repos/meta-openembedded
|
||||
git clone -b master https://github.com/wolfSSL/meta-wolfssl.git repos/meta-wolfssl
|
||||
|
||||
ln -s ../repos/poky layers/poky
|
||||
ln -s ../repos/meta-raspberrypi layers/meta-raspberrypi
|
||||
ln -s ../repos/meta-openembedded layers/meta-openembedded
|
||||
ln -s ../repos/meta-wolfssl layers/meta-wolfssl
|
||||
```
|
||||
|
||||
Also checks that required host tools (gcc, python3, etc.) are installed and
|
||||
generates a `.envrc` for direnv.
|
||||
|
||||
### `make configure`
|
||||
|
||||
Runs `configure.sh`, which:
|
||||
|
||||
1. Sources `oe-init-build-env` to create the `build/` directory
|
||||
2. Writes `build/conf/bblayers.conf` with all layer paths (poky, meta-oe,
|
||||
meta-raspberrypi, meta-wolfssl, meta-network-overrides)
|
||||
3. Writes an RPi5-specific config block into `build/conf/local.conf`:
|
||||
- `MACHINE = "raspberrypi5"`
|
||||
- SSH, HDMI, Wi-Fi, Bluetooth, systemd
|
||||
- Shared download/sstate cache directories
|
||||
|
||||
Manual equivalent: run `source layers/poky/oe-init-build-env build` and edit
|
||||
`build/conf/bblayers.conf` and `build/conf/local.conf` by hand.
|
||||
|
||||
### `make generate-fips-conf BUNDLE=<path>`
|
||||
|
||||
Runs `generate-fips-conf.sh`, which inspects a wolfSSL FIPS Ready `.zip`
|
||||
bundle and generates `conf/wolfssl-fips-ready.conf` containing:
|
||||
|
||||
- `PREFERRED_PROVIDER_virtual/wolfssl = "wolfssl-fips-ready"` (and linuxkm)
|
||||
- `WOLFSSL_VERSION`, `WOLFSSL_SRC_SHA` (SHA256 of the zip)
|
||||
- `WOLFSSL_LICENSE_MD5` (MD5 of the COPYING file inside the zip)
|
||||
- `WOLFSSL_SRC_DIR` (absolute path to the directory containing the zip)
|
||||
- `FIPS_HASH` placeholder (auto-extracted during build via QEMU)
|
||||
|
||||
Manual equivalent: compute the SHA256 and license MD5 yourself and write the
|
||||
conf file with the correct variable assignments.
|
||||
|
||||
### `make fips-on`
|
||||
|
||||
Enables the FIPS overrides by modifying two files:
|
||||
|
||||
1. **`build/conf/bblayers.conf`** - adds `layers/meta-wolfssl-overrides` to
|
||||
the `BBLAYERS` list (after `meta-wolfssl`)
|
||||
2. **`build/conf/local.conf`** - appends a config block:
|
||||
```
|
||||
require conf/wolfssl-fips-ready.conf
|
||||
INITRAMFS_IMAGE = "core-image-minimal-initramfs"
|
||||
INITRAMFS_IMAGE_BUNDLE = "1"
|
||||
```
|
||||
|
||||
The overrides layer (`meta-wolfssl-overrides`) provides:
|
||||
- Image recipes (`wolfssl-fips-ready-image`, `wolfssl-fips-ready-image-qemu`)
|
||||
- Kernel bbappends that apply the wolfSSL randomness patches and FIPS crypto
|
||||
config (`CONFIG_CRYPTO_FIPS=y`, module signing)
|
||||
- An initramfs bbappend that adds `wolfssl-linuxkm` to the initramfs and
|
||||
injects `modprobe libwolfssl` into the init script
|
||||
- bbappends for libgcrypt, GnuTLS, wolfProvider, OpenSSL, curl, and OpenSSH
|
||||
to use wolfSSL as the crypto backend
|
||||
|
||||
### `make build` (RPi5)
|
||||
|
||||
Sources the bitbake environment and runs:
|
||||
|
||||
```bash
|
||||
source layers/poky/oe-init-build-env build
|
||||
bitbake wolfssl-fips-ready-image # if FIPS enabled
|
||||
bitbake core-image-base # if FIPS disabled
|
||||
```
|
||||
|
||||
This builds the full image for `MACHINE = "raspberrypi5"` using
|
||||
`linux-raspberrypi` (6.6). The kernel is bundled with the initramfs
|
||||
containing the wolfSSL FIPS kernel module. Output is a `.wic.bz2` image
|
||||
in `build/tmp/deploy/images/raspberrypi5/`.
|
||||
|
||||
### `make qemu`
|
||||
|
||||
Sources the bitbake environment and runs:
|
||||
|
||||
```bash
|
||||
source layers/poky/oe-init-build-env build
|
||||
bitbake -R conf/qemu-override.conf wolfssl-fips-ready-image-qemu
|
||||
```
|
||||
|
||||
The `-R conf/qemu-override.conf` flag layers additional config on top of
|
||||
`local.conf` without modifying it. The override conf:
|
||||
|
||||
- Sets `MACHINE = "qemuarm64"`
|
||||
- Switches kernel to `linux-yocto` (since `linux-raspberrypi` doesn't
|
||||
support QEMU)
|
||||
- Sets `INITRAMFS_IMAGE` and `INITRAMFS_IMAGE_BUNDLE` for the QEMU kernel
|
||||
- Clears RPi device trees (`KERNEL_DEVICETREE = ""`)
|
||||
- Adds `IMAGE_CLASSES += "qemuboot"` and `IMAGE_FSTYPES += "ext4"` (normally
|
||||
provided by `qemuarm64.conf`, but `-R` is parsed too late for machine
|
||||
config files to take effect)
|
||||
- Provides all `QB_*` variables (`QB_MACHINE`, `QB_CPU`, `QB_SERIAL_OPT`,
|
||||
etc.) that `runqemu` needs to launch the VM
|
||||
- Sets `console=ttyAMA0` (QEMU's virtual PL011 UART, replacing RPi's
|
||||
`ttyAMA10`)
|
||||
- Removes RPi-specific packages (`linux-firmware-rpidistro-bcm43455`)
|
||||
|
||||
Output is an `.ext4` rootfs and `.qemuboot.conf` in
|
||||
`build/tmp/deploy/images/qemuarm64/`.
|
||||
|
||||
### `make run-qemu`
|
||||
|
||||
Sources the bitbake environment and runs:
|
||||
|
||||
```bash
|
||||
source layers/poky/oe-init-build-env build
|
||||
runqemu /path/to/wolfssl-fips-ready-image-qemu-qemuarm64.qemuboot.conf nographic
|
||||
```
|
||||
|
||||
The `.qemuboot.conf` file contains all the QEMU launch parameters (machine
|
||||
type, CPU, memory, drives, network, serial). `runqemu` reads it and
|
||||
constructs the full `qemu-system-aarch64` command line. The `nographic` flag
|
||||
redirects the VM console to stdio.
|
||||
|
||||
### `make fips-off`
|
||||
|
||||
Reverses `make fips-on`:
|
||||
|
||||
1. Removes `meta-wolfssl-overrides` from `build/conf/bblayers.conf`
|
||||
2. Removes the FIPS config block (including `INITRAMFS_IMAGE` settings) from
|
||||
`build/conf/local.conf`
|
||||
|
||||
After this, `make build` produces a plain `core-image-base` without wolfSSL.
|
||||
|
||||
### `make ip-<address>` / `make ip-dhcp`
|
||||
|
||||
Runs `set-network.sh` to write a systemd-networkd config file at
|
||||
`layers/meta-network-overrides/recipes-core/network-config/files/20-wired.network`.
|
||||
This file is baked into the image at build time - it cannot be changed after
|
||||
flashing without rebuilding.
|
||||
|
||||
## License
|
||||
|
||||
This layer configuration is provided under the MIT license. wolfSSL itself is
|
||||
dual-licensed under GPLv2 and a commercial license. See
|
||||
[wolfSSL licensing](https://www.wolfssl.com/license/) for details.
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
# QEMU override configuration
|
||||
#
|
||||
# Applied via 'bitbake -R' to override RPi5 settings for QEMU builds.
|
||||
# This file is layered on top of local.conf - last assignment wins.
|
||||
|
||||
MACHINE = "qemuarm64"
|
||||
|
||||
# Use the standard QEMU kernel instead of linux-raspberrypi
|
||||
PREFERRED_PROVIDER_virtual/kernel = "linux-yocto"
|
||||
|
||||
# Bundle initramfs into the kernel so wolfSSL FIPS module loads at early boot
|
||||
# (same mechanism as RPi - these must be global so linux-yocto picks them up)
|
||||
INITRAMFS_IMAGE = "core-image-minimal-initramfs"
|
||||
INITRAMFS_IMAGE_BUNDLE = "1"
|
||||
|
||||
# Clear RPi device trees - linux-yocto doesn't have broadcom/ DTBs
|
||||
KERNEL_DEVICETREE = ""
|
||||
|
||||
# Generate .qemuboot.conf so runqemu can launch the image
|
||||
# (qemuarm64.conf / qemu.inc are not parsed because -R is too late for
|
||||
# machine config resolution - we must replicate the essential settings here)
|
||||
IMAGE_CLASSES += "qemuboot"
|
||||
IMAGE_FSTYPES += "ext4"
|
||||
|
||||
# QEMU machine settings (from qemuarm64.conf - not parsed via -R)
|
||||
QB_SYSTEM_NAME = "qemu-system-aarch64"
|
||||
QB_MACHINE = "-machine virt"
|
||||
QB_CPU = "-cpu max"
|
||||
QB_SMP = "-smp 4"
|
||||
QB_CPU_KVM = "-cpu host -machine gic-version=3"
|
||||
QB_GRAPHICS = "-device virtio-gpu-pci"
|
||||
QB_OPT_APPEND = "-device qemu-xhci -device usb-tablet -device usb-kbd"
|
||||
QB_TAP_OPT = "-netdev tap,id=net0,ifname=@TAP@,script=no,downscript=no"
|
||||
QB_NETWORK_DEVICE = "-device virtio-net-pci,netdev=net0,mac=@MAC@"
|
||||
QB_ROOTFS_OPT = "-drive id=disk0,file=@ROOTFS@,if=none,format=raw -device virtio-blk-pci,drive=disk0"
|
||||
QB_SERIAL_OPT = "-device virtio-serial-pci -chardev null,id=virtcon -device virtconsole,chardev=virtcon"
|
||||
QB_TCPSERIAL_OPT = "-device virtio-serial-pci -chardev socket,id=virtcon,port=@PORT@,host=127.0.0.1,nodelay=on -device virtconsole,chardev=virtcon"
|
||||
|
||||
# Serial console - override RPi's ttyAMA10/tty1 with QEMU's ttyAMA0
|
||||
SERIAL_CONSOLES = "115200;ttyAMA0 115200;hvc0"
|
||||
CMDLINE_DEBUG = ""
|
||||
QB_KERNEL_CMDLINE_APPEND = "console=ttyAMA0"
|
||||
|
||||
# Remove RPi-specific packages that don't exist for QEMU
|
||||
IMAGE_INSTALL:remove = "linux-firmware-rpidistro-bcm43455"
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# configure.sh - Initialize Yocto build directory and write configuration
|
||||
#
|
||||
# Called by 'make configure'. Safe to re-run — managed config block is replaced.
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
BUILD_DIR="${SCRIPT_DIR}/build"
|
||||
LAYERS_DIR="${SCRIPT_DIR}/layers"
|
||||
POKY_DIR="${LAYERS_DIR}/poky"
|
||||
|
||||
if [ ! -d "${POKY_DIR}" ]; then
|
||||
echo "Error: poky not found. Run ./setup.sh first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Initialize build directory if needed
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
if [ ! -d "${BUILD_DIR}/conf" ]; then
|
||||
echo "[INIT] Initializing build directory..."
|
||||
source "${POKY_DIR}/oe-init-build-env" "${BUILD_DIR}" > /dev/null 2>&1
|
||||
fi
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Write bblayers.conf
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
echo "[CONFIG] Writing bblayers.conf..."
|
||||
|
||||
cat > "${BUILD_DIR}/conf/bblayers.conf" <<BBLAYERS
|
||||
# POKY_BBLAYERS_CONF_VERSION is increased each time build/conf/bblayers.conf
|
||||
# changes incompatibly
|
||||
POKY_BBLAYERS_CONF_VERSION = "2"
|
||||
|
||||
BBPATH = "\${TOPDIR}"
|
||||
BBFILES ?= ""
|
||||
|
||||
BBLAYERS ?= " \\
|
||||
${LAYERS_DIR}/poky/meta \\
|
||||
${LAYERS_DIR}/poky/meta-poky \\
|
||||
${LAYERS_DIR}/meta-openembedded/meta-oe \\
|
||||
${LAYERS_DIR}/meta-openembedded/meta-python \\
|
||||
${LAYERS_DIR}/meta-openembedded/meta-networking \\
|
||||
${LAYERS_DIR}/meta-openembedded/meta-multimedia \\
|
||||
${LAYERS_DIR}/meta-raspberrypi \\
|
||||
${LAYERS_DIR}/meta-wolfssl \\
|
||||
${LAYERS_DIR}/meta-network-overrides \\
|
||||
"
|
||||
BBLAYERS
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Write RPi5 config block in local.conf
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
echo "[CONFIG] Writing RPi5 configuration to local.conf..."
|
||||
|
||||
CONFIG_MARKER="# ==== meta-wolfssl-linux-fips managed config ===="
|
||||
|
||||
# Remove any existing managed config block
|
||||
sed -i "/${CONFIG_MARKER}/,/${CONFIG_MARKER} END/d" "${BUILD_DIR}/conf/local.conf"
|
||||
|
||||
# Append fresh config block
|
||||
cat >> "${BUILD_DIR}/conf/local.conf" <<'LOCALCONF'
|
||||
# ==== meta-wolfssl-linux-fips managed config ====
|
||||
# This block is managed by 'make configure'. To change, edit configure.sh
|
||||
# and re-run 'make configure'.
|
||||
|
||||
MACHINE = "raspberrypi5"
|
||||
|
||||
# ---- Image features ----
|
||||
IMAGE_FEATURES += "ssh-server-openssh"
|
||||
|
||||
# ---- Display / GPU ----
|
||||
MACHINE_FEATURES:append = " vc4graphics"
|
||||
VC4DTBO = "vc4-kms-v3d"
|
||||
|
||||
# ---- Early HDMI console ----
|
||||
# Force HDMI output and route kernel console to framebuffer
|
||||
RPI_EXTRA_CONFIG = "hdmi_force_hotplug=1\nhdmi_group=1\nhdmi_mode=16\ndisable_overscan=1"
|
||||
CMDLINE_DEBUG = "console=tty1"
|
||||
SERIAL_CONSOLES:append = " 115200;tty1"
|
||||
|
||||
# ---- Wi-Fi and Bluetooth ----
|
||||
DISTRO_FEATURES:append = " wifi bluetooth"
|
||||
IMAGE_INSTALL:append = " linux-firmware-rpidistro-bcm43455 bluez5 wpa-supplicant network-config"
|
||||
LICENSE_FLAGS_ACCEPTED:append = " synaptics-killswitch"
|
||||
|
||||
# ---- systemd ----
|
||||
DISTRO_FEATURES:append = " systemd usrmerge"
|
||||
VIRTUAL-RUNTIME_init_manager = "systemd"
|
||||
VIRTUAL-RUNTIME_initscripts = "systemd-compat-units"
|
||||
|
||||
# ---- Serial console (debug) ----
|
||||
ENABLE_UART = "1"
|
||||
|
||||
# ---- U-Boot ----
|
||||
# Disabled — U-Boot can cause HDMI issues on RPi5, boot kernel directly
|
||||
RPI_USE_U_BOOT = "0"
|
||||
|
||||
# ---- Shared caches (keep outside build dir for reuse) ----
|
||||
DL_DIR ?= "${TOPDIR}/../downloads"
|
||||
SSTATE_DIR ?= "${TOPDIR}/../sstate-cache"
|
||||
|
||||
# ---- Host SDK architecture ----
|
||||
SDKMACHINE ?= "x86_64"
|
||||
|
||||
# ---- Disable SPDX license metadata generation ----
|
||||
INHERIT:remove = "create-spdx"
|
||||
# ==== meta-wolfssl-linux-fips managed config ==== END
|
||||
LOCALCONF
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Ensure default network config exists (DHCP)
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
NETCONF="${SCRIPT_DIR}/layers/meta-network-overrides/recipes-core/network-config/files/20-wired.network"
|
||||
|
||||
if [ ! -f "${NETCONF}" ]; then
|
||||
echo "[CONFIG] Writing default network config (DHCP)..."
|
||||
mkdir -p "$(dirname "${NETCONF}")"
|
||||
cat > "${NETCONF}" <<'NETEOF'
|
||||
[Match]
|
||||
Name=end0 eth0
|
||||
|
||||
[Network]
|
||||
DHCP=yes
|
||||
NETEOF
|
||||
fi
|
||||
|
||||
echo "[CONFIG] Done. Run 'make build' to build the image."
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# generate-fips-conf.sh - Generate wolfssl-fips-ready.conf from a FIPS Ready .zip bundle
|
||||
#
|
||||
# Usage: ./generate-fips-conf.sh /path/to/wolfssl-x.x.x-gplv3-fips-ready.zip
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
CONF_FILE="${SCRIPT_DIR}/conf/wolfssl-fips-ready.conf"
|
||||
|
||||
ZIP_PATH="$1"
|
||||
|
||||
if [ -z "${ZIP_PATH}" ]; then
|
||||
echo "Usage: $0 /path/to/wolfssl-x.x.x-gplv3-fips-ready.zip"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "${ZIP_PATH}" ]; then
|
||||
echo "Error: File not found: ${ZIP_PATH}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ZIP_NAME="$(basename "${ZIP_PATH}")"
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Extract version from filename
|
||||
# Expected format: wolfssl-X.X.X-gplv3-fips-ready.zip
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
VERSION="$(echo "${ZIP_NAME}" | sed -n 's/wolfssl-\([0-9]*\.[0-9]*\.[0-9]*\).*/\1/p')"
|
||||
|
||||
if [ -z "${VERSION}" ]; then
|
||||
echo "Error: Could not extract version from filename: ${ZIP_NAME}"
|
||||
echo "Expected format: wolfssl-X.X.X-gplv3-fips-ready.zip"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "=== Generating FIPS Ready Configuration ==="
|
||||
echo ""
|
||||
echo "Bundle: ${ZIP_NAME}"
|
||||
echo "Version: ${VERSION}"
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Compute SHA256 of the bundle
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
echo ""
|
||||
echo "[HASH] Computing SHA256..."
|
||||
BUNDLE_SHA="$(sha256sum "${ZIP_PATH}" | awk '{print $1}')"
|
||||
echo " SHA256: ${BUNDLE_SHA}"
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Extract COPYING file and compute MD5
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
echo "[HASH] Extracting license MD5..."
|
||||
TMPDIR="$(mktemp -d)"
|
||||
trap "rm -rf ${TMPDIR}" EXIT
|
||||
|
||||
# Try to find COPYING in the zip — it may be at the root or in a subdirectory
|
||||
COPYING_PATH="$(unzip -l "${ZIP_PATH}" | grep -m1 'COPYING$' | awk '{print $NF}')"
|
||||
|
||||
if [ -z "${COPYING_PATH}" ]; then
|
||||
echo "Warning: COPYING file not found in zip. You'll need to set WOLFSSL_LICENSE_MD5 manually."
|
||||
LICENSE_MD5=""
|
||||
else
|
||||
unzip -q -o "${ZIP_PATH}" "${COPYING_PATH}" -d "${TMPDIR}"
|
||||
LICENSE_MD5="$(md5sum "${TMPDIR}/${COPYING_PATH}" | awk '{print $1}')"
|
||||
echo " License MD5: ${LICENSE_MD5}"
|
||||
fi
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Derive bundle name
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
SRC_NAME="${ZIP_NAME%.zip}"
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Resolve bundle directory (absolute path)
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
BUNDLE_DIR="$(cd "$(dirname "${ZIP_PATH}")" && pwd)"
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Generate conf file
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
echo "[CONFIG] Writing conf/wolfssl-fips-ready.conf..."
|
||||
mkdir -p "$(dirname "${CONF_FILE}")"
|
||||
|
||||
cat > "${CONF_FILE}" <<EOF
|
||||
# wolfSSL FIPS Ready Configuration
|
||||
#
|
||||
# Auto-generated by generate-fips-conf.sh from:
|
||||
# ${ZIP_NAME}
|
||||
#
|
||||
# To regenerate: make generate-fips-conf BUNDLE=/path/to/bundle.zip
|
||||
|
||||
# Use wolfSSL FIPS Ready as the wolfSSL provider
|
||||
PREFERRED_PROVIDER_virtual/wolfssl = "wolfssl-fips-ready"
|
||||
PREFERRED_PROVIDER_wolfssl = "wolfssl-fips-ready"
|
||||
|
||||
# FIPS hash mode: "auto" (QEMU-based extraction) or "manual" (use static FIPS_HASH)
|
||||
WOLFSSL_FIPS_HASH_MODE ?= "auto"
|
||||
WOLFSSL_FIPS_HASH_MODE_LINUXKM ?= "auto"
|
||||
|
||||
# wolfSSL FIPS kernel module provider
|
||||
PREFERRED_PROVIDER_virtual/wolfssl-linuxkm ?= "wolfssl-linuxkm-fips-ready"
|
||||
PREFERRED_PROVIDER_wolfssl-linuxkm ?= "wolfssl-linuxkm-fips-ready"
|
||||
|
||||
# Bundle version
|
||||
WOLFSSL_VERSION = "${VERSION}"
|
||||
|
||||
# SHA256 checksum of the bundle .zip
|
||||
WOLFSSL_SRC_SHA = "${BUNDLE_SHA}"
|
||||
|
||||
# MD5 of the COPYING license file in the bundle
|
||||
WOLFSSL_LICENSE_MD5 = "${LICENSE_MD5}"
|
||||
|
||||
# Bundle name (directory name inside the zip, without extension)
|
||||
WOLFSSL_SRC = "${SRC_NAME}"
|
||||
|
||||
# Bundle archive filename
|
||||
WOLFSSL_BUNDLE_FILE = "${ZIP_NAME}"
|
||||
|
||||
# Directory containing the .zip bundle (absolute path to where bundle lives)
|
||||
WOLFSSL_SRC_DIR = "${BUNDLE_DIR}"
|
||||
|
||||
# FIPS hash (set after first build if using manual mode)
|
||||
# Leave as-is for auto mode — it will be extracted automatically
|
||||
FIPS_HASH = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
|
||||
EOF
|
||||
|
||||
echo ""
|
||||
echo "=== Done ==="
|
||||
echo ""
|
||||
echo "Generated: conf/wolfssl-fips-ready.conf"
|
||||
echo "Bundle: ${BUNDLE_DIR}/${ZIP_NAME}"
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo " make fips-on"
|
||||
echo " make clean"
|
||||
echo " make build"
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
# Layer configuration for meta-network-overrides
|
||||
BBPATH .= ":${LAYERDIR}"
|
||||
|
||||
BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \
|
||||
${LAYERDIR}/recipes-*/*/*.bbappend"
|
||||
|
||||
BBFILE_COLLECTIONS += "meta-network-overrides"
|
||||
BBFILE_PATTERN_meta-network-overrides = "^${LAYERDIR}/"
|
||||
BBFILE_PRIORITY_meta-network-overrides = "6"
|
||||
|
||||
LAYERDEPENDS_meta-network-overrides = "core"
|
||||
LAYERSERIES_COMPAT_meta-network-overrides = "scarthgap"
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
SUMMARY = "systemd-networkd configuration for wired ethernet"
|
||||
LICENSE = "MIT"
|
||||
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
|
||||
|
||||
SRC_URI = "file://20-wired.network"
|
||||
|
||||
S = "${WORKDIR}"
|
||||
|
||||
do_install() {
|
||||
install -d ${D}${sysconfdir}/systemd/network
|
||||
install -m 0644 ${WORKDIR}/20-wired.network ${D}${sysconfdir}/systemd/network/20-wired.network
|
||||
}
|
||||
|
||||
FILES:${PN} = "${sysconfdir}/systemd/network/20-wired.network"
|
||||
|
||||
RDEPENDS:${PN} = "systemd"
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
# Layer configuration for meta-wolfssl-overrides
|
||||
#
|
||||
# This layer provides bbappends and overrides for meta-wolfssl recipes,
|
||||
# customizing wolfSSL for the RPi5 FIPS build.
|
||||
|
||||
# We have a conf and classes directory, add to BBPATH
|
||||
BBPATH .= ":${LAYERDIR}"
|
||||
|
||||
# We have recipes-* directories, add to BBFILES
|
||||
BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \
|
||||
${LAYERDIR}/recipes-*/*/*.bbappend"
|
||||
|
||||
BBFILE_COLLECTIONS += "meta-wolfssl-overrides"
|
||||
BBFILE_PATTERN_meta-wolfssl-overrides = "^${LAYERDIR}/"
|
||||
BBFILE_PRIORITY_meta-wolfssl-overrides = "7"
|
||||
|
||||
LAYERDEPENDS_meta-wolfssl-overrides = "core wolfssl"
|
||||
LAYERSERIES_COMPAT_meta-wolfssl-overrides = "scarthgap"
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
# OpenSSH ptest modifications for wolfProvider FIPS testing
|
||||
|
||||
require ${WOLFSSL_LAYERDIR}/inc/wolfprovider/openssh/openssh-enable-wolfprovider.inc
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
# Configure OpenSSL to use wolfProvider in replace-default mode
|
||||
|
||||
require ${WOLFSSL_LAYERDIR}/inc/wolfprovider/openssl/openssl-enable-wolfprovider-replace-default.inc
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
# Add wolfSSL FIPS kernel module to initramfs for early boot loading
|
||||
|
||||
PACKAGE_INSTALL:append = " wolfssl-linuxkm"
|
||||
|
||||
inherit wolfssl-initramfs
|
||||
|
||||
ROOTFS_POSTPROCESS_COMMAND += "wolfssl_initramfs_run_depmod; "
|
||||
ROOTFS_POSTPROCESS_COMMAND += "wolfssl_initramfs_inject_after_loadmodules; "
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
SUMMARY = "QEMU image with wolfSSL FIPS Ready cryptography"
|
||||
DESCRIPTION = "QEMU (aarch64) image based on core-image-base with wolfSSL FIPS Ready \
|
||||
crypto backend powering libgcrypt, gnutls, and wolfProvider (replace-default mode). \
|
||||
Use this to test the wolfSSL FIPS Ready integration without physical hardware."
|
||||
|
||||
LICENSE = "MIT"
|
||||
|
||||
inherit wolfssl-compatibility
|
||||
|
||||
python __anonymous() {
|
||||
virtual_provider = d.getVar('PREFERRED_PROVIDER_virtual/wolfssl') or ''
|
||||
wolfssl_provider = d.getVar('PREFERRED_PROVIDER_wolfssl') or ''
|
||||
|
||||
valid_fips_providers = ('wolfssl-fips', 'wolfssl-fips-ready')
|
||||
|
||||
if virtual_provider not in valid_fips_providers:
|
||||
bb.fatal("wolfssl-fips-ready-image-qemu requires PREFERRED_PROVIDER_virtual/wolfssl "
|
||||
"to be one of %s. Current: '%s'. "
|
||||
"Run 'make generate-fips-conf' and 'make fips-on' first."
|
||||
% (valid_fips_providers, virtual_provider))
|
||||
|
||||
if wolfssl_provider not in valid_fips_providers:
|
||||
bb.fatal("wolfssl-fips-ready-image-qemu requires PREFERRED_PROVIDER_wolfssl "
|
||||
"to be one of %s. Current: '%s'. "
|
||||
"Run 'make generate-fips-conf' and 'make fips-on' first."
|
||||
% (valid_fips_providers, wolfssl_provider))
|
||||
}
|
||||
|
||||
require recipes-core/images/core-image-base.bb
|
||||
|
||||
# NOTE: INITRAMFS_IMAGE and INITRAMFS_IMAGE_BUNDLE are set in conf/qemu-override.conf
|
||||
# (they must be global so linux-yocto picks them up, not scoped to this image recipe)
|
||||
|
||||
# wolfSSL FIPS Ready core
|
||||
IMAGE_INSTALL:append = " wolfssl wolfcrypttest wolfcryptbenchmark"
|
||||
|
||||
# FIPS Ready subsystems
|
||||
IMAGE_INSTALL:append = " libgcrypt libgcrypt-ptest"
|
||||
IMAGE_INSTALL:append = " gnutls gnutls-dev gnutls-bin gnutls-fips"
|
||||
IMAGE_INSTALL:append = " wolfssl-gnutls-wrapper wolfssl-gnutls-wrapper-dev"
|
||||
IMAGE_INSTALL:append = " wolfprovider openssl openssl-bin wolfprovidercmd wolfproviderenv"
|
||||
|
||||
# Test utilities
|
||||
IMAGE_INSTALL:append = " ptest-runner bash make glibc-utils binutils ldd curl cryptsetup"
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
SUMMARY = "RPi5 image with wolfSSL FIPS Ready cryptography"
|
||||
DESCRIPTION = "Raspberry Pi 5 image based on core-image-base with wolfSSL FIPS Ready \
|
||||
crypto backend powering libgcrypt, gnutls, and wolfProvider (replace-default mode)."
|
||||
|
||||
LICENSE = "MIT"
|
||||
|
||||
inherit wolfssl-compatibility
|
||||
|
||||
python __anonymous() {
|
||||
virtual_provider = d.getVar('PREFERRED_PROVIDER_virtual/wolfssl') or ''
|
||||
wolfssl_provider = d.getVar('PREFERRED_PROVIDER_wolfssl') or ''
|
||||
|
||||
valid_fips_providers = ('wolfssl-fips', 'wolfssl-fips-ready')
|
||||
|
||||
if virtual_provider not in valid_fips_providers:
|
||||
bb.fatal("wolfssl-fips-ready-image requires PREFERRED_PROVIDER_virtual/wolfssl "
|
||||
"to be one of %s. Current: '%s'. "
|
||||
"Run 'make generate-fips-conf' and 'make fips-on' first."
|
||||
% (valid_fips_providers, virtual_provider))
|
||||
|
||||
if wolfssl_provider not in valid_fips_providers:
|
||||
bb.fatal("wolfssl-fips-ready-image requires PREFERRED_PROVIDER_wolfssl "
|
||||
"to be one of %s. Current: '%s'. "
|
||||
"Run 'make generate-fips-conf' and 'make fips-on' first."
|
||||
% (valid_fips_providers, wolfssl_provider))
|
||||
}
|
||||
|
||||
require recipes-core/images/core-image-base.bb
|
||||
|
||||
# Use initramfs-bundled kernel so wolfSSL FIPS module loads before rootfs
|
||||
IMAGE_BOOT_FILES:remove = "Image;kernel_2712.img"
|
||||
IMAGE_BOOT_FILES:append = " Image-initramfs-${MACHINE}.bin;kernel_2712.img"
|
||||
|
||||
# wolfSSL FIPS Ready core
|
||||
IMAGE_INSTALL:append = " wolfssl wolfcrypttest wolfcryptbenchmark"
|
||||
|
||||
# FIPS Ready subsystems
|
||||
IMAGE_INSTALL:append = " libgcrypt libgcrypt-ptest"
|
||||
IMAGE_INSTALL:append = " gnutls gnutls-dev gnutls-bin gnutls-fips"
|
||||
IMAGE_INSTALL:append = " wolfssl-gnutls-wrapper wolfssl-gnutls-wrapper-dev"
|
||||
IMAGE_INSTALL:append = " wolfprovider openssl openssl-bin wolfprovidercmd wolfproviderenv"
|
||||
|
||||
# Test utilities
|
||||
IMAGE_INSTALL:append = " ptest-runner bash make glibc-utils binutils ldd curl cryptsetup"
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
CONFIG_CRYPTO_FIPS=y
|
||||
CONFIG_CRYPTO_MANAGER=y
|
||||
CONFIG_CRYPTO_MANAGER2=y
|
||||
CONFIG_CRYPTO_USER=m
|
||||
CONFIG_MODULE_SIG=y
|
||||
CONFIG_MODULE_SIG_FORMAT=y
|
||||
CONFIG_MODULE_SIG_ALL=y
|
||||
CONFIG_MODULE_SIG_SHA256=y
|
||||
CONFIG_CRYPTO_ALGAPI=y
|
||||
CONFIG_CRYPTO_ALGAPI2=y
|
||||
CONFIG_CRYPTO_AEAD=y
|
||||
CONFIG_CRYPTO_AEAD2=y
|
||||
CONFIG_CRYPTO_SKCIPHER=y
|
||||
CONFIG_CRYPTO_SKCIPHER2=y
|
||||
CONFIG_CRYPTO_HASH=y
|
||||
CONFIG_CRYPTO_HASH2=y
|
||||
CONFIG_CRYPTO_RNG=y
|
||||
CONFIG_CRYPTO_RNG2=y
|
||||
CONFIG_CRYPTO_AKCIPHER=y
|
||||
CONFIG_CRYPTO_AKCIPHER2=y
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
# Apply wolfSSL kernel randomness patches for FIPS DRBG integration
|
||||
# Adds callback hooks to drivers/char/random.c and include/linux/random.h
|
||||
# allowing wolfSSL kernel module (libwolfssl.ko) to register its FIPS-certified
|
||||
# DRBG implementation with the kernel.
|
||||
|
||||
inherit wolfssl-kernel-random
|
||||
WOLFSSL_KERNEL_RANDOM_PATCH = "6.12"
|
||||
|
||||
# Enable kernel FIPS mode and crypto subsystem
|
||||
FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
|
||||
SRC_URI:append = " file://fips-crypto.cfg"
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
# Apply wolfSSL kernel randomness patches for FIPS DRBG integration
|
||||
# Adds callback hooks to drivers/char/random.c and include/linux/random.h
|
||||
# allowing wolfSSL kernel module (libwolfssl.ko) to register its FIPS-certified
|
||||
# DRBG implementation with the kernel.
|
||||
|
||||
inherit wolfssl-kernel-random
|
||||
WOLFSSL_KERNEL_RANDOM_PATCH = "6.12"
|
||||
|
||||
# Enable kernel FIPS mode and crypto subsystem
|
||||
FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
|
||||
SRC_URI:append = " file://fips-crypto.cfg"
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
# Configure curl with wolfProvider support
|
||||
|
||||
require ${WOLFSSL_LAYERDIR}/inc/curl/curl-enable-wolfprovider-fips.inc
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
# Configure gnupg for libgcrypt with wolfSSL backend
|
||||
|
||||
require ${WOLFSSL_LAYERDIR}/inc/gnupg/gnupg-enable-libgcrypt-wolfssl.inc
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
# Configure gnutls to use wolfSSL backend
|
||||
|
||||
require ${WOLFSSL_LAYERDIR}/inc/gnutls/gnutls-enable-wolfssl.inc
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
# Configure libgcrypt to use wolfSSL backend
|
||||
|
||||
require ${WOLFSSL_LAYERDIR}/inc/libgcrypt/libgcrypt-enable-wolfssl.inc
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
# nettle 3.10 required for gnutls 3.8.11
|
||||
|
||||
require ${WOLFSSL_LAYERDIR}/inc/nettle/nettle.inc
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
From: meta-wolfssl-overrides <noreply@wolfssl.com>
|
||||
Subject: [PATCH] Fix KRB5KDF missing wc_AesInit causing segfault
|
||||
|
||||
The Aes struct in wp_kdf_krb5kdf_derive is never initialized with
|
||||
wc_AesInit. In FIPS mode wc_AesCbcEncrypt dereferences uninitialized
|
||||
internal pointers causing a segfault. Additionally wc_AesFree is called
|
||||
unconditionally at the end, so early-exit error paths (wrong key size
|
||||
etc.) also segfault on the uninitialized struct.
|
||||
|
||||
Fix by zeroing the struct at declaration and calling wc_AesInit
|
||||
immediately, before any validation that could skip to wc_AesFree.
|
||||
|
||||
Signed-off-by: meta-wolfssl-overrides <noreply@wolfssl.com>
|
||||
---
|
||||
--- a/src/wp_krb5kdf.c
|
||||
+++ b/src/wp_krb5kdf.c
|
||||
@@ -446,7 +446,7 @@
|
||||
size_t osize = 0;
|
||||
size_t cipherLen = 0;
|
||||
int rc;
|
||||
- Aes aes;
|
||||
+ Aes aes = {0};
|
||||
byte block[AES_BLOCK_SIZE];
|
||||
byte cipherBlock[AES_BLOCK_SIZE];
|
||||
byte *plain = NULL;
|
||||
@@ -457,6 +457,13 @@
|
||||
if (!wolfssl_prov_is_running()) {
|
||||
ok = 0;
|
||||
}
|
||||
+ if (ok) {
|
||||
+ rc = wc_AesInit(&aes, NULL, INVALID_DEVID);
|
||||
+ if (rc != 0) {
|
||||
+ WOLFPROV_MSG_DEBUG_RETCODE(WP_LOG_LEVEL_DEBUG, "wc_AesInit", rc);
|
||||
+ ok = 0;
|
||||
+ }
|
||||
+ }
|
||||
if (ok && (!wp_kdf_krb5kdf_set_ctx_params(ctx, params))) {
|
||||
ok = 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
# Fix n_fold unsigned underflow segfault in KRB5KDF with small constants
|
||||
FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
|
||||
SRC_URI:append = " file://0001-fix-krb5kdf-n_fold-unsigned-underflow.patch"
|
||||
|
||||
# Disable the feature check for manual image configuration
|
||||
require ${WOLFSSL_LAYERDIR}/inc/wolfssl-manual-config.inc
|
||||
|
||||
# Enable unit tests for wolfprovider replace default mode
|
||||
require ${WOLFSSL_LAYERDIR}/inc/wolfprovider/wolfprovider-enable-replace-default-unittest.inc
|
||||
require ${WOLFSSL_LAYERDIR}/inc/wolfprovider/wolfprovider-enable-unittest.inc
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
# Configure wolfSSL FIPS Ready with libgcrypt, gnutls, and wolfProvider support
|
||||
#
|
||||
# These .inc files from meta-wolfssl enable the necessary wolfSSL configure
|
||||
# options for each subsystem to use wolfSSL FIPS Ready as the crypto backend.
|
||||
|
||||
require ${WOLFSSL_LAYERDIR}/inc/wolfssl-fips-ready/wolfssl-enable-libgcrypt.inc
|
||||
require ${WOLFSSL_LAYERDIR}/inc/wolfssl-fips-ready/wolfssl-enable-gnutls.inc
|
||||
require ${WOLFSSL_LAYERDIR}/inc/wolfprovider/wolfssl-enable-wolfprovider-fips-ready.inc
|
||||
|
||||
# Fix for bundle missing stamp-h.in required by automake
|
||||
do_configure_create_stamph() {
|
||||
if [ ! -f ${S}/stamp-h.in ]; then
|
||||
touch ${S}/stamp-h.in
|
||||
fi
|
||||
}
|
||||
|
||||
addtask do_configure_create_stamph after do_patch before do_configure
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
# RPi5 (Cortex-A76 aarch64) — enable ARM assembly and LKCAPI registration
|
||||
EXTRA_OECONF:append:raspberrypi5 = " --enable-linuxkm-lkcapi-register=all-kconfig"
|
||||
|
||||
# QEMU (aarch64) — enable LKCAPI registration for virtual machine testing
|
||||
EXTRA_OECONF:append:qemuarm64 = " --enable-linuxkm-lkcapi-register=all-kconfig"
|
||||
|
||||
# Sign the module with the kernel's own key to prevent "module verification failed" taint
|
||||
require ${WOLFSSL_LAYERDIR}/inc/wolfssl-linuxkm/wolfssl-linuxkm-sign-module.inc
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# set-network.sh - Write systemd-networkd config for the RPi5 image
|
||||
#
|
||||
# Usage:
|
||||
# ./set-network.sh dhcp
|
||||
# ./set-network.sh static 192.168.1.100 [GATEWAY] [PREFIX] [DNS]
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
NETCONF="${SCRIPT_DIR}/layers/meta-network-overrides/recipes-core/network-config/files/20-wired.network"
|
||||
|
||||
MODE="$1"
|
||||
ADDR="$2"
|
||||
GW="${3:-}"
|
||||
PREFIX="${4:-24}"
|
||||
DNS="${5:-8.8.8.8}"
|
||||
|
||||
if [ "${MODE}" = "dhcp" ]; then
|
||||
echo "[CONFIG] Setting network to DHCP..."
|
||||
cat > "${NETCONF}" <<'EOF'
|
||||
[Match]
|
||||
Name=end0 eth0
|
||||
|
||||
[Network]
|
||||
DHCP=yes
|
||||
EOF
|
||||
|
||||
elif [ "${MODE}" = "static" ] && [ -n "${ADDR}" ]; then
|
||||
# Auto-detect gateway if not provided: use .1 of the same subnet
|
||||
if [ -z "${GW}" ]; then
|
||||
GW="$(echo "${ADDR}" | sed 's/\.[0-9]*$/.1/')"
|
||||
fi
|
||||
|
||||
echo "[CONFIG] Setting static IP: ${ADDR}/${PREFIX} gw ${GW} dns ${DNS}"
|
||||
cat > "${NETCONF}" <<EOF
|
||||
[Match]
|
||||
Name=end0 eth0
|
||||
|
||||
[Network]
|
||||
Address=${ADDR}/${PREFIX}
|
||||
Gateway=${GW}
|
||||
DNS=${DNS}
|
||||
EOF
|
||||
|
||||
else
|
||||
echo "Usage:"
|
||||
echo " $0 dhcp"
|
||||
echo " $0 static <IP> [GATEWAY] [PREFIX] [DNS]"
|
||||
echo ""
|
||||
echo "Examples:"
|
||||
echo " $0 dhcp"
|
||||
echo " $0 static 192.168.1.100"
|
||||
echo " $0 static 192.168.1.100 192.168.1.1 24 8.8.8.8"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
cat "${NETCONF}"
|
||||
echo ""
|
||||
echo "Rebuild the image with 'make build' to apply."
|
||||
|
|
@ -0,0 +1,180 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# setup.sh - Clone Yocto layers and verify host tools for RPi5 Scarthgap build
|
||||
#
|
||||
# Usage: ./setup.sh [--ignore-missing-packages]
|
||||
#
|
||||
# This script is idempotent — safe to run multiple times.
|
||||
#
|
||||
# Repos are cloned into repos/ (git-ignored). Symlinks are created in layers/
|
||||
# so that layers/ is the single directory referenced by bblayers.conf.
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
IGNORE_MISSING=false
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
--ignore-missing-packages) IGNORE_MISSING=true ;;
|
||||
esac
|
||||
done
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
BRANCH="scarthgap"
|
||||
REPOS_DIR="${SCRIPT_DIR}/repos"
|
||||
LAYERS_DIR="${SCRIPT_DIR}/layers"
|
||||
|
||||
echo "=== Yocto Scarthgap RPi5 Setup ==="
|
||||
echo "Working directory: ${SCRIPT_DIR}"
|
||||
echo ""
|
||||
|
||||
cd "${SCRIPT_DIR}"
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Check required host tools
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
echo "--- Checking host tools ---"
|
||||
|
||||
MISSING=()
|
||||
|
||||
REQUIRED_TOOLS=(
|
||||
git
|
||||
gcc
|
||||
g++
|
||||
make
|
||||
python3
|
||||
wget
|
||||
diffstat
|
||||
unzip
|
||||
makeinfo
|
||||
chrpath
|
||||
socat
|
||||
cpio
|
||||
xz
|
||||
zstd
|
||||
lz4
|
||||
file
|
||||
gawk
|
||||
locale
|
||||
)
|
||||
|
||||
for tool in "${REQUIRED_TOOLS[@]}"; do
|
||||
if command -v "${tool}" &> /dev/null; then
|
||||
echo " [OK] ${tool}"
|
||||
else
|
||||
echo " [MISS] ${tool}"
|
||||
MISSING+=("${tool}")
|
||||
fi
|
||||
done
|
||||
|
||||
if [ ${#MISSING[@]} -gt 0 ]; then
|
||||
echo ""
|
||||
echo "WARNING: Missing required tools: ${MISSING[*]}"
|
||||
echo ""
|
||||
echo "On Debian/Ubuntu, install them with:"
|
||||
echo " sudo apt install gawk wget git diffstat unzip texinfo gcc build-essential \\"
|
||||
echo " chrpath socat cpio python3 python3-pip python3-pexpect xz-utils \\"
|
||||
echo " debianutils iputils-ping python3-git python3-jinja2 python3-subunit \\"
|
||||
echo " zstd liblz4-tool file locales libacl1"
|
||||
echo ""
|
||||
if [ "${IGNORE_MISSING}" = true ]; then
|
||||
echo "Continuing anyway (--ignore-missing-packages)."
|
||||
else
|
||||
echo "Re-run with --ignore-missing-packages to skip this check."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Clone repos
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
mkdir -p "${REPOS_DIR}"
|
||||
|
||||
echo "--- Cloning repos (branch: ${BRANCH}) ---"
|
||||
|
||||
clone_repo() {
|
||||
local url="$1"
|
||||
local dir="$2"
|
||||
local branch="$3"
|
||||
|
||||
if [ -d "${REPOS_DIR}/${dir}" ]; then
|
||||
echo " [SKIP] ${dir} already exists"
|
||||
else
|
||||
echo " [CLONE] ${dir}"
|
||||
git clone -b "${branch}" "${url}" "${REPOS_DIR}/${dir}"
|
||||
fi
|
||||
}
|
||||
|
||||
clone_repo "git://git.yoctoproject.org/poky" "poky" "${BRANCH}"
|
||||
clone_repo "git://git.yoctoproject.org/meta-raspberrypi" "meta-raspberrypi" "${BRANCH}"
|
||||
clone_repo "git://git.openembedded.org/meta-openembedded" "meta-openembedded" "${BRANCH}"
|
||||
clone_repo "https://github.com/wolfSSL/meta-wolfssl.git" "meta-wolfssl" "master"
|
||||
|
||||
echo ""
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Create symlinks in layers/
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
echo "--- Linking repos into layers/ ---"
|
||||
|
||||
link_layer() {
|
||||
local name="$1"
|
||||
|
||||
if [ -L "${LAYERS_DIR}/${name}" ]; then
|
||||
echo " [SKIP] layers/${name} symlink exists"
|
||||
elif [ -d "${LAYERS_DIR}/${name}" ]; then
|
||||
echo " [SKIP] layers/${name} is a directory (not a symlink)"
|
||||
else
|
||||
echo " [LINK] layers/${name} -> repos/${name}"
|
||||
ln -s "../repos/${name}" "${LAYERS_DIR}/${name}"
|
||||
fi
|
||||
}
|
||||
|
||||
link_layer "poky"
|
||||
link_layer "meta-raspberrypi"
|
||||
link_layer "meta-openembedded"
|
||||
link_layer "meta-wolfssl"
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Generate .envrc for direnv
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
echo "--- Generating .envrc ---"
|
||||
|
||||
if [ -f "${SCRIPT_DIR}/.envrc" ]; then
|
||||
echo " [SKIP] .envrc already exists"
|
||||
else
|
||||
cat > "${SCRIPT_DIR}/.envrc" <<'ENVRC'
|
||||
# Auto-source the Yocto/bitbake build environment when entering this directory.
|
||||
# Managed by direnv — run 'direnv allow' after any changes to this file.
|
||||
|
||||
POKY_DIR="${PWD}/layers/poky"
|
||||
BUILD_DIR="${PWD}/build"
|
||||
|
||||
if [ ! -d "${POKY_DIR}" ]; then
|
||||
echo "direnv: layers/poky not found — run ./setup.sh first"
|
||||
elif [ ! -d "${BUILD_DIR}/conf" ]; then
|
||||
echo "direnv: build/ not initialized — run 'make configure' next"
|
||||
else
|
||||
# Suppress the oe-init-build-env banner output
|
||||
source "${POKY_DIR}/oe-init-build-env" "${BUILD_DIR}" > /dev/null 2>&1
|
||||
|
||||
# Stay in the original directory (oe-init-build-env changes cwd)
|
||||
cd "${ENVRC_DIR:-${PWD}}"
|
||||
fi
|
||||
ENVRC
|
||||
echo " [OK] .envrc generated"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== Setup Complete ==="
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo " make configure - Initialize build dir and write local.conf"
|
||||
echo " make build - Build core-image-base"
|
||||
echo ""
|
||||
Loading…
Reference in New Issue