Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions .github/actions/wolfhal-build/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: 'Build a wolfHAL board'
description: 'Cross-build the wolfHAL example for one board and assert the port is linked'

inputs:
board:
description: 'directory name under wolfHAL/boards'
required: true
wolfssl-root:
description: 'path to the wolfSSL source tree to compile wolfCrypt from'
required: false
default: '/tmp/wolfssl'

runs:
using: composite
steps:
- shell: bash
run: |
set -euo pipefail
board='${{ inputs.board }}'
[ -f "wolfHAL/boards/$board/board.mk" ] \
|| { echo "no such board: wolfHAL/boards/$board/board.mk"; exit 1; }

make -C wolfHAL BOARD="$board" WOLFSSL_ROOT='${{ inputs.wolfssl-root }}' -j"$(nproc)"

# The board declares its own toolchain, so ask make rather than assume
# a prefix here.
cross=$(make -s -C wolfHAL BOARD="$board" print-CROSS_COMPILE)
elf=wolfHAL/wolfcrypt_test.elf
arch=$(file -b "$elf")
echo "$arch"
case "$arch" in
*x86-64*) echo "FAIL: host binary, the cross toolchain was not used"; exit 1 ;;
esac

# A build with the port configured away would still link and still be
# the right arch, so assert the callback is registered and reaches a
# driver. Which modes are offloaded is the board's choice, so accept any.
"${cross}nm" "$elf" | grep -q ' T wc_wolfHAL_RegisterDevice' \
|| { echo "FAIL: wolfHAL port not linked"; exit 1; }
modes=$("${cross}objdump" -d "$elf" --disassemble=wc_wolfHAL_CryptoDevCb \
| grep -oE 'whal_Aes(Ecb|Cbc|Gcm|Ccm)_Oneshot' | sort -u | tr '\n' ' ')
[ -n "$modes" ] || { echo "FAIL: no AES mode dispatched to wolfHAL"; exit 1; }
echo "$board offloads: $modes"

make -C wolfHAL BOARD="$board" clean >/dev/null
6 changes: 6 additions & 0 deletions .github/examples-manifest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1650,3 +1650,9 @@ examples:
path: utasker
mode: skip
reason: "uTasker project task files; no standalone build"

- id: wolfhal
path: wolfHAL
tier: cross
profile: all
mode: build-only
1 change: 1 addition & 0 deletions .github/scripts/manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ def job_built_paths():
("java", "java/https-url"), ("rt1060", "RT1060"),
("csharp", "CSharp/wolfSSL-TLS-pq-Client"),
("psa", "psa"),
("wolfhal", "wolfHAL"),
("bsdkm", "kernel/bsdkm"),
("cmake", "cmake")):
if job in jobs_seen:
Expand Down
6 changes: 6 additions & 0 deletions .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,12 @@ jobs:
with:
caller_run_id: ${{ github.run_id }}

wolfhal:
needs: [refs]
uses: ./.github/workflows/wolfhal.yml
with:
caller_run_id: ${{ github.run_id }}

ebpf:
needs: [refs]
uses: ./.github/workflows/ebpf.yml
Expand Down
81 changes: 81 additions & 0 deletions .github/workflows/wolfhal.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
name: wolfHAL

on:
push:
branches: [master]
paths:
- 'wolfHAL/**'
- '.github/workflows/wolfhal.yml'
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
paths:
- 'wolfHAL/**'
- '.github/workflows/wolfhal.yml'
# No cron: nightly.yml calls this, so the nightly stays one run and one triage writer
workflow_call:
inputs:
caller_run_id:
description: 'run id of the calling workflow; keeps a called run in its own concurrency group'
type: string
default: ''
workflow_dispatch:

# github.workflow is the CALLER's name in a called workflow, so hardcode ours
concurrency:
group: ${{ inputs.caller_run_id && format('wolfhal-call-{0}', inputs.caller_run_id) || format('wolfhal-{0}', github.ref) }}
cancel-in-progress: ${{ !inputs.caller_run_id }}

permissions:
contents: read

jobs:
resolve:
uses: ./.github/workflows/_resolve-wolfssl.yml
with:
# master only: the wolfHAL crypto-callback port (wolfcrypt/src/port/wolfHAL)
# is not in any released tag
refs: master

wolfhal:
needs: resolve
name: Build / wolfHAL boards, wolfSSL ${{ matrix.wolfssl_ref }}
if: github.event_name != 'pull_request' || github.event.pull_request.draft == false
runs-on: ubuntu-24.04
strategy:
fail-fast: false
matrix:
wolfssl_ref: ${{ fromJson(needs.resolve.outputs.refs_json) }}
timeout-minutes: 30
steps:
# The wolfHAL drivers come from the pinned submodule at wolfHAL/wolfHAL.
- uses: actions/checkout@v5
with:
submodules: true

- uses: ./.github/actions/apt-update

# Every toolchain any board under wolfHAL/boards needs, installed once for
# the whole run. A board added with a different target adds its packages
# here; the per-board prefix comes from that board's CROSS_COMPILE.
- name: Install toolchains
run: |
set -euo pipefail
sudo apt-get install -y --no-install-recommends \
gcc-arm-none-eabi binutils-arm-none-eabi libnewlib-arm-none-eabi

- name: Fetch wolfSSL
run: |
set -euo pipefail
# --branch, or every leg silently clones the default branch and the
# stable leg builds master
bash "$GITHUB_WORKSPACE/.github/scripts/git-clone-retry.sh" -q --depth 1 --branch '${{ matrix.wolfssl_ref }}' \
https://github.com/wolfSSL/wolfssl /tmp/wolfssl
git -C /tmp/wolfssl log -1 --format='wolfssl at ${{ matrix.wolfssl_ref }}: %h %s'

# One step per board. A new board is not tested until it is listed
# here; `if: !cancelled()` keeps a broken board from hiding the rest.
- name: Build stm32wb55xx_nucleo
if: '!cancelled()'
uses: ./.github/actions/wolfhal-build
with:
board: stm32wb55xx_nucleo
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,6 @@
[submodule "android/wolfcryptjni-ndk-gradle/wolfcrypt-jni"]
path = android/wolfcryptjni-ndk-gradle/wolfcrypt-jni
url = https://github.com/wolfssl/wolfcrypt-jni
[submodule "wolfHAL/wolfHAL"]
path = wolfHAL/wolfHAL
url = https://github.com/wolfSSL/wolfHAL.git
1 change: 1 addition & 0 deletions wolfHAL/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
wolfcrypt_test.bin
Comment thread
AlexLanzano marked this conversation as resolved.
88 changes: 88 additions & 0 deletions wolfHAL/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# Makefile for the wolfCrypt + wolfHAL example
#
# Usage:
# make
# make BOARD=stm32wb55xx_nucleo
# make flash

BOARD ?= stm32wb55xx_nucleo

WOLFSSL_ROOT ?= $(abspath ../../wolfssl)
WHAL_DIR ?= $(abspath wolfHAL)
GCC_PATH ?=

TARGET = wolfcrypt_test
IMAGE ?= $(TARGET).bin

# Toolchain, the direct-API-mapping selection, the wolfHAL drivers this board
# needs (BOARD_SOURCE) and the linker script.
include boards/$(BOARD)/board.mk

CFLAGS += -I. -I$(WHAL_DIR) -I$(WOLFSSL_ROOT) -DWOLFSSL_USER_SETTINGS

# Application
SRC = main.c
SRC += syscalls.c

# Board and wolfHAL drivers
SRC += $(BOARD_SOURCE)

# wolfCrypt core
SRC += $(WOLFSSL_ROOT)/wolfcrypt/src/wc_port.c
SRC += $(WOLFSSL_ROOT)/wolfcrypt/src/memory.c
SRC += $(WOLFSSL_ROOT)/wolfcrypt/src/aes.c
SRC += $(WOLFSSL_ROOT)/wolfcrypt/src/cryptocb.c
SRC += $(WOLFSSL_ROOT)/wolfcrypt/src/sha256.c
SRC += $(WOLFSSL_ROOT)/wolfcrypt/src/hash.c
SRC += $(WOLFSSL_ROOT)/wolfcrypt/src/random.c
SRC += $(WOLFSSL_ROOT)/wolfcrypt/src/logging.c
SRC += $(WOLFSSL_ROOT)/wolfcrypt/src/error.c
SRC += $(WOLFSSL_ROOT)/wolfcrypt/src/wc_encrypt.c
SRC += $(WOLFSSL_ROOT)/wolfcrypt/src/sp_int.c
SRC += $(WOLFSSL_ROOT)/wolfcrypt/test/test.c
SRC += $(WOLFSSL_ROOT)/wolfcrypt/benchmark/benchmark.c

# wolfSSL's wolfHAL port
SRC += $(WOLFSSL_ROOT)/wolfcrypt/src/port/wolfHAL/wolfhal.c

# Objects go under build/ with their path flattened into the name. Compiling in
# place would drop ARM objects into the wolfSSL and wolfHAL checkouts, where
# they collide with those trees' own builds.
OBJDIR = build
objname = $(OBJDIR)/$(subst /,_,$(patsubst /%,%,$(basename $(1)))).o
OBJ = $(foreach s,$(SRC),$(call objname,$(s)))

all: $(TARGET).bin
$(SIZE) $(TARGET).elf

$(TARGET).elf: $(OBJ)
$(GCC) $(LDFLAGS) -o $@ $^ $(LDLIBS)

$(TARGET).bin: $(TARGET).elf
$(OBJCOPY) -O binary $< $@

$(OBJDIR):
mkdir -p $@

define compile_rule
$(call objname,$(1)): $(1) | $(OBJDIR)
$$(GCC) $$(CFLAGS) -c -o $$@ $$<
endef
$(foreach s,$(SRC),$(eval $(call compile_rule,$(s))))

# Flash via openocd (ST-LINK on the Nucleo).
flash: $(TARGET).bin
openocd -f interface/stlink.cfg -f target/stm32wbx.cfg \
-c "program $(TARGET).bin 0x08000000 verify reset exit"

clean:
rm -rf $(OBJDIR) $(TARGET).elf $(TARGET).bin

# Query a variable, e.g. `make -s BOARD=x print-CROSS_COMPILE`. Lets CI ask the
# board for its toolchain rather than keeping a second copy of that mapping.
print-%:
@echo "$($*)"

.PHONY: all flash clean

-include $(OBJ:.o=.d)
44 changes: 44 additions & 0 deletions wolfHAL/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# wolfCrypt + wolfHAL Example

Runs the wolfCrypt test suite and benchmark on bare metal, with AES and the RNG
served by the board's hardware.

[wolfHAL](https://github.com/wolfSSL/wolfHAL) is a portable hardware abstraction
layer with no OS, toolchain or platform dependencies. It provides a common API
for accessing hardware functionality, with the platform-specific configuration
kept in board files.

wolfSSL reaches it through `wolfcrypt/src/port/wolfHAL`, which registers a
crypto callback at `wolfCrypt_Init()`. wolfCrypt then routes AES to the
accelerator and falls back to software for anything the board does not offload.

## Supported boards

| Board | Offloaded |
| --- | --- |
| `stm32wb55xx_nucleo` | AES-ECB/CBC/GCM/CCM on AES1, RNG |

Each lives in `boards/<name>/` and owns its clock, pin and device setup, its
toolchain, and its linker script.

## Building

Needs `arm-none-eabi-gcc` and a wolfSSL checkout beside this repository:

```sh
sudo apt install gcc-arm-none-eabi binutils-arm-none-eabi libnewlib-arm-none-eabi
git submodule update --init wolfHAL # the wolfHAL drivers
make # or: make BOARD=<name>
make flash
```

`WOLFSSL_ROOT` defaults to `../../wolfssl` and `WHAL_DIR` to the submodule;
override either on the command line. wolfCrypt is compiled from source rather
than linked, so no installed `libwolfssl` is involved.

## Adding a board

Copy `boards/stm32wb55xx_nucleo/` and adjust `board.h` (device initializers plus
the `WC_WOLFHAL_*_DEV` macros naming what to offload), `board.c` (bring-up),
`board.mk` (toolchain, driver list), `linker.ld` and `ivt.c`. Then add a build
step for it in `.github/workflows/wolfhal.yml`.
Loading
Loading