Skip to content
Draft
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
114 changes: 114 additions & 0 deletions .github/workflows/build-and-test-autosar.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
name: Build and Test AUTOSAR Port

on:
push:
branches: [ 'master', 'main', 'release/**' ]
pull_request:
branches: [ '*' ]

permissions:
contents: read

jobs:
csm-smoke:
strategy:
matrix:
asan: [ 'ASAN=0', 'ASAN=1' ]
runs-on: ubuntu-latest
# The job compiles wolfSSL + wolfcrypt from scratch three times (POSIX
# server, csm_smoke, ap_smoke), each with ML-DSA/ML-KEM enabled, and the
# ASAN=1 matrix variant adds substantial compile overhead. 5 minutes was
# too tight on a 4-vCPU runner and both matrix jobs hit the wall.
timeout-minutes: 15

steps:
- uses: actions/checkout@v4

- name: Checkout wolfssl
uses: actions/checkout@v4
with:
repository: wolfssl/wolfssl
path: wolfssl

- name: Build POSIX server
run: |
cd examples/posix/wh_posix_server
${{ matrix.asan }} make -j WOLFSSL_DIR=../../../wolfssl

- name: Build csm_smoke
run: |
cd port/autosar/classic/examples/csm_smoke
${{ matrix.asan }} make -j WOLFSSL_DIR=../../../../../wolfssl

- name: Build ap_smoke (Adaptive)
run: |
cd port/autosar/adaptive/examples/ap_smoke
cmake -S . -B build -DWOLFHSM_DIR=../../../../.. -DWOLFSSL_DIR=../../../../../wolfssl
cmake --build build --parallel

# Classic Crypto Driver smoke. Server is started/torn down per
# smoke binary because the POSIX server's TCP transport tends to
# close after the client disconnects.
- name: Run csm_smoke (Classic)
run: |
cd examples/posix/wh_posix_server
./Build/wh_posix_server.elf --type tcp &
SRV=$!
# Wait until the server is LISTENING, checking passively with ss.
# A connect-probe (e.g. /dev/tcp) would be accept()ed as the
# server's single client and consume its only accept slot, leaving
# the real client unable to be serviced — so check state, don't
# connect. The client also retries connect on its own, so this is
# purely to avoid a noisy first-connect race.
for i in $(seq 1 50); do
ss -ltn 2>/dev/null | grep -q ':23456 ' && break
sleep 0.2
done
# Guard against a blocking-socket hang: the client should finish in
# seconds, so cap it well under the job timeout and surface a clear
# failure instead of silently eating the whole budget.
# Capture exit codes via '|| var=$?': GitHub runs this with
# 'bash -e', so a bare non-zero command (the smoke binary failing,
# or 'wait' returning the server's SIGTERM code) would abort the
# step before we can inspect the code or clean up the server.
rc=0
( cd ../../../port/autosar/classic/examples/csm_smoke && timeout 120 ./Build/csm_smoke ) || rc=$?
if [ $rc -eq 124 ]; then echo "csm_smoke timed out — likely a hang, not a slow build"; fi
# Send TERM, then surface the server's exit status: a crash
# mid-test (SIGSEGV / assert) must fail the CI job, not be
# masked by the client's clean exit.
kill -TERM $SRV 2>/dev/null || true
srv_rc=0
wait "$SRV" || srv_rc=$?
# bash reports 143 (=128+15) for a clean SIGTERM exit; treat
# that as success. Any other non-zero is a real server failure.
if [ $srv_rc -ne 0 ] && [ $srv_rc -ne 143 ]; then
echo "wh_posix_server exited with $srv_rc — failing CI"
exit 1
fi
exit $rc

# Adaptive CryptoProvider smoke against a fresh server instance.
- name: Run ap_smoke (Adaptive)
run: |
cd examples/posix/wh_posix_server
./Build/wh_posix_server.elf --type tcp &
SRV=$!
# Passive listen check — see csm_smoke step for why we must not
# open a real connection here.
for i in $(seq 1 50); do
ss -ltn 2>/dev/null | grep -q ':23456 ' && break
sleep 0.2
done
# See csm_smoke step for why exit codes are captured via '|| var=$?'.
rc=0
( cd ../../../port/autosar/adaptive/examples/ap_smoke && timeout 120 ./build/ap_smoke ) || rc=$?
if [ $rc -eq 124 ]; then echo "ap_smoke timed out — likely a hang, not a slow build"; fi
kill -TERM $SRV 2>/dev/null || true
srv_rc=0
wait "$SRV" || srv_rc=$?
if [ $srv_rc -ne 0 ] && [ $srv_rc -ne 143 ]; then
echo "wh_posix_server exited with $srv_rc — failing CI"
exit 1
fi
exit $rc
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,7 @@ scan_out/*

# Test output
test-suite.log
port/autosar/adaptive/examples/*/build/

# Local wolfssl checkout for CI-style smoke builds
/wolfssl/
77 changes: 77 additions & 0 deletions port/autosar/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# wolfHSM AUTOSAR Port

This port exposes the wolfHSM client API as standard AUTOSAR Crypto interfaces:

- **Classic Platform** (`classic/`) — implements `AUTOSAR_SWS_CryptoDriver`
R22-11. Drop-in replacement for an OEM/vendor Crypto Driver, sits below
CryIf in any AUTOSAR Classic BSW (MICROSAR / RTA-BSW / EB tresos).
- **Adaptive Platform** (`adaptive/`) — implements an `ara::crypto`
`CryptoProvider` per `AUTOSAR_SWS_Cryptography` R22-11. Registered via an
AP Execution Manifest, plugs into any AP runtime supporting providers.

Both layers translate AUTOSAR-shaped calls into `wh_Client_*` calls against
a wolfHSM server running on the secure core. Key material never leaves the
server; only handles cross the boundary.

## Layout

```
port/autosar/
├── common/ algorithm and key-id mapping between AUTOSAR and wolfHSM
├── classic/ AUTOSAR Classic Crypto Driver (C, R22-11)
├── adaptive/ AUTOSAR Adaptive CryptoProvider (C++17, R22-11)
└── docs/ integration notes and algorithm coverage table
```

## Status

- **Classic** — hash (SHA-256 / 384 / 512), AES (ECB/CBC/CTR/GCM), CMAC,
ECDSA P-256, Ed25519, RSA-PKCS#1-v1.5, ECDH P-256, HKDF, CMAC-KDF, RNG,
key management. Sync and real-async dispatch through `Crypto_MainFunction`
driving wolfHSM `*Request` / `*Response`.
- **Adaptive** — `WolfhsmCryptoProvider` with 9 context classes:
`RandomGeneratorCtx`, `HashFunctionCtx`, `SymmetricBlockCipherCtx`,
`AuthCipherCtx`, `MessageAuthnCodeCtx`, `SignerPrivateCtx` /
`VerifierPublicCtx`, `KeyAgreementPrivateCtx`,
`KeyDerivationFunctionCtx`, `KeyStorageProvider`.
- **Tests**: `classic/examples/csm_smoke/` (per-category C harness, ~25
tests) and `adaptive/examples/ap_smoke/` (per-cluster C++ harness, 9
tests). Both run against `examples/posix/wh_posix_server` over TCP and
are wired into `.github/workflows/build-and-test-autosar.yml`.

See `docs/algorithm_coverage.md` for the per-primitive matrix (sync /
async / Adaptive coverage), and `docs/client_workarounds.md` for the one
client-side translation kept while wolfHSM's verify-handler return
contract evolves.

## Quickstart

```sh
# Terminal 1 — run the wolfHSM POSIX server.
cd examples/posix/wh_posix_server && make
./Build/wh_posix_server.elf --type tcp

# Terminal 2 — build and run csm_smoke (Classic).
cd port/autosar/classic/examples/csm_smoke && make
./Build/csm_smoke

# Restart the server, then build and run ap_smoke (Adaptive).
cd port/autosar/adaptive/examples/ap_smoke
cmake -S . -B build && cmake --build build
./build/ap_smoke
```

Both binaries print one OK line per test category and `all tests passed`
on success.

## Licensing

This port is GPLv3 like the rest of wolfHSM (`../../LICENSE`). Commercial
integrators ship under wolfSSL's commercial license — same dual-license
model as wolfSSL / wolfCrypt. The port contains no vendor-supplied BSW
headers; `Crypto.h` and the `ara/crypto` headers are written from the
public AUTOSAR SWS documents.

"AUTOSAR-conformant" labeling is restricted to AUTOSAR Partners. This port
**implements** the AUTOSAR R22-11 interfaces; conformance certification is
out of scope.
55 changes: 55 additions & 0 deletions port/autosar/adaptive/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Build script for the wolfHSM AUTOSAR Adaptive CryptoProvider library.
# Produces libwolfhsm_ara_crypto.{a,so} that an Adaptive integrator links
# into their CryptoProvider adapter.

cmake_minimum_required(VERSION 3.13)
project(wolfhsm_ara_crypto CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

if(NOT DEFINED WOLFHSM_DIR)
set(WOLFHSM_DIR ${CMAKE_CURRENT_LIST_DIR}/../../..)
endif()
if(NOT DEFINED WOLFSSL_DIR)
set(WOLFSSL_DIR ${WOLFHSM_DIR}/../wolfssl)
endif()
# Resolve to absolute paths so they don't get reinterpreted against this
# target's source dir. This matters when a relative -DWOLFHSM_DIR is
# passed for a standalone build; when inherited from a parent project the
# values are already absolute and this is a no-op.
get_filename_component(WOLFHSM_DIR "${WOLFHSM_DIR}" ABSOLUTE
BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
get_filename_component(WOLFSSL_DIR "${WOLFSSL_DIR}" ABSOLUTE
BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")

set(SRC src/crypto_provider.cpp)

add_library(wolfhsm_ara_crypto ${SRC})

target_include_directories(wolfhsm_ara_crypto PUBLIC
include
${WOLFHSM_DIR}
${WOLFSSL_DIR}
)
# Integrators override WOLFHSM_CONFIG_DIR to point at their own
# wolfhsm_cfg.h / user_settings.h. The default points at the shared
# port/autosar config so the library builds out of the box for
# verification.
if(NOT DEFINED WOLFHSM_CONFIG_DIR)
set(WOLFHSM_CONFIG_DIR ${CMAKE_CURRENT_LIST_DIR}/../common/config)
endif()
target_include_directories(wolfhsm_ara_crypto PRIVATE
${WOLFHSM_CONFIG_DIR}
${CMAKE_CURRENT_LIST_DIR}/../common/include
)

target_compile_definitions(wolfhsm_ara_crypto PRIVATE
WOLFHSM_CFG
WOLFSSL_USER_SETTINGS
)
target_compile_options(wolfhsm_ara_crypto PRIVATE -Wall -Wextra -Werror)

# Integrators link this library into their ara::crypto::cryp::CryptoProvider
# adapter. See docs/integration_adaptive.md for the bridging pattern.
65 changes: 65 additions & 0 deletions port/autosar/adaptive/examples/ap_smoke/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Build the Adaptive CryptoProvider smoke binary.
#
# Usage (from port/autosar/adaptive/examples/ap_smoke/):
# cmake -S . -B build -DWOLFHSM_DIR=../../../../.. -DWOLFSSL_DIR=/path/to/wolfssl
# cmake --build build
#
# Run alongside examples/posix/wh_posix_server (TCP, default port 23456):
# ./build/ap_smoke

cmake_minimum_required(VERSION 3.13)
project(ap_smoke CXX C)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_C_STANDARD 99)

if(NOT DEFINED WOLFHSM_DIR)
set(WOLFHSM_DIR ${CMAKE_CURRENT_LIST_DIR}/../../../../..)
endif()
if(NOT DEFINED WOLFSSL_DIR)
set(WOLFSSL_DIR ${WOLFHSM_DIR}/../wolfssl)
endif()
# Normalize to absolute paths anchored at this example's source dir. A
# relative -DWOLFHSM_DIR is meant relative to where cmake was invoked
# (here), but CMake resolves relative include dirs against each target's
# own source dir — so the inherited value would point at the wrong place
# inside the add_subdirectory()'d adaptive library. Resolving now makes
# the paths unambiguous everywhere they're inherited.
get_filename_component(WOLFHSM_DIR "${WOLFHSM_DIR}" ABSOLUTE
BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
get_filename_component(WOLFSSL_DIR "${WOLFSSL_DIR}" ABSOLUTE
BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
set(WOLFHSM_CONFIG_DIR ${WOLFHSM_DIR}/port/autosar/common/config)

# Pull in the Adaptive library.
add_subdirectory(${WOLFHSM_DIR}/port/autosar/adaptive
${CMAKE_BINARY_DIR}/wolfhsm_ara_crypto)

# Glob the wolfHSM client + wolfSSL sources we need at link time.
file(GLOB WOLFHSM_SRC ${WOLFHSM_DIR}/src/*.c)
file(GLOB WOLFHSM_POSIX ${WOLFHSM_DIR}/port/posix/*.c)
file(GLOB WOLFCRYPT_SRC ${WOLFSSL_DIR}/wolfcrypt/src/*.c)
file(GLOB WOLFSSL_SRC ${WOLFSSL_DIR}/src/*.c)

add_executable(ap_smoke
ap_smoke.cpp
${WOLFHSM_SRC}
${WOLFHSM_POSIX}
${WOLFCRYPT_SRC}
${WOLFSSL_SRC}
)

target_compile_definitions(ap_smoke PRIVATE
_POSIX_C_SOURCE=200809L
WOLFHSM_CFG
WOLFSSL_USER_SETTINGS
WC_USE_DEVID=0x5748534D
)
target_include_directories(ap_smoke PRIVATE
${WOLFHSM_DIR}
${WOLFSSL_DIR}
${WOLFHSM_CONFIG_DIR}
)
target_link_libraries(ap_smoke PRIVATE wolfhsm_ara_crypto pthread m)
Loading
Loading