diff --git a/meta-wolfssl-linux-fips/.gitignore b/meta-wolfssl-linux-fips/.gitignore new file mode 100644 index 00000000..466a04b3 --- /dev/null +++ b/meta-wolfssl-linux-fips/.gitignore @@ -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/ diff --git a/meta-wolfssl-linux-fips/Makefile b/meta-wolfssl-linux-fips/Makefile new file mode 100644 index 00000000..168313f3 --- /dev/null +++ b/meta-wolfssl-linux-fips/Makefile @@ -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' to build the FIPS 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-
: 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= - 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-
- 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." diff --git a/meta-wolfssl-linux-fips/README.md b/meta-wolfssl-linux-fips/README.md new file mode 100644 index 00000000..5f763ac5 --- /dev/null +++ b/meta-wolfssl-linux-fips/README.md @@ -0,0 +1,620 @@ +# 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. Install +direnv once: + +```bash +sudo apt install -y direnv + +# Add the hook to ~/.bashrc (only needed once) +echo 'eval "$(direnv hook bash)"' >> ~/.bashrc +source ~/.bashrc + +# After running setup.sh, allow direnv to load the generated .envrc +direnv allow +``` + +### 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=` | 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-
` | 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 fips-ready https://github.com/night1rider/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=` + +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-
` / `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. diff --git a/meta-wolfssl-linux-fips/conf/qemu-override.conf b/meta-wolfssl-linux-fips/conf/qemu-override.conf new file mode 100644 index 00000000..6c4da169 --- /dev/null +++ b/meta-wolfssl-linux-fips/conf/qemu-override.conf @@ -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" diff --git a/meta-wolfssl-linux-fips/configure.sh b/meta-wolfssl-linux-fips/configure.sh new file mode 100755 index 00000000..f06ebda6 --- /dev/null +++ b/meta-wolfssl-linux-fips/configure.sh @@ -0,0 +1,132 @@ +#!/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" <> "${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" +# ==== 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." diff --git a/meta-wolfssl-linux-fips/generate-fips-conf.sh b/meta-wolfssl-linux-fips/generate-fips-conf.sh new file mode 100755 index 00000000..bef28495 --- /dev/null +++ b/meta-wolfssl-linux-fips/generate-fips-conf.sh @@ -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}" < +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 +--- +--- 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; + } diff --git a/meta-wolfssl-linux-fips/layers/meta-wolfssl-overrides/recipes-wolfssl/wolfprovider/wolfprovider_%.bbappend b/meta-wolfssl-linux-fips/layers/meta-wolfssl-overrides/recipes-wolfssl/wolfprovider/wolfprovider_%.bbappend new file mode 100644 index 00000000..235dee2b --- /dev/null +++ b/meta-wolfssl-linux-fips/layers/meta-wolfssl-overrides/recipes-wolfssl/wolfprovider/wolfprovider_%.bbappend @@ -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 diff --git a/meta-wolfssl-linux-fips/layers/meta-wolfssl-overrides/recipes-wolfssl/wolfssl/wolfssl-fips-ready.bbappend b/meta-wolfssl-linux-fips/layers/meta-wolfssl-overrides/recipes-wolfssl/wolfssl/wolfssl-fips-ready.bbappend new file mode 100644 index 00000000..084065b7 --- /dev/null +++ b/meta-wolfssl-linux-fips/layers/meta-wolfssl-overrides/recipes-wolfssl/wolfssl/wolfssl-fips-ready.bbappend @@ -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 diff --git a/meta-wolfssl-linux-fips/layers/meta-wolfssl-overrides/recipes-wolfssl/wolfssl/wolfssl-linuxkm-fips-ready.bbappend b/meta-wolfssl-linux-fips/layers/meta-wolfssl-overrides/recipes-wolfssl/wolfssl/wolfssl-linuxkm-fips-ready.bbappend new file mode 100644 index 00000000..b43f2b78 --- /dev/null +++ b/meta-wolfssl-linux-fips/layers/meta-wolfssl-overrides/recipes-wolfssl/wolfssl/wolfssl-linuxkm-fips-ready.bbappend @@ -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 diff --git a/meta-wolfssl-linux-fips/set-network.sh b/meta-wolfssl-linux-fips/set-network.sh new file mode 100755 index 00000000..f9d79a94 --- /dev/null +++ b/meta-wolfssl-linux-fips/set-network.sh @@ -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}" < [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." diff --git a/meta-wolfssl-linux-fips/setup.sh b/meta-wolfssl-linux-fips/setup.sh new file mode 100755 index 00000000..e836fa21 --- /dev/null +++ b/meta-wolfssl-linux-fips/setup.sh @@ -0,0 +1,178 @@ +#!/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/night1rider/meta-wolfssl.git" "meta-wolfssl" "fips-ready" + +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}" ] && [ -d "${BUILD_DIR}/conf" ]; then + # 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}}" +else + echo "direnv: poky or build dir not found — run ./setup.sh first" +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 ""