Skip to content
Merged
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
38 changes: 38 additions & 0 deletions .github/examples-manifest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,16 @@ profiles:
--enable-extra-pqc-hybrids --enable-slhdsa=yes,sha2
--enable-experimental --enable-tls13 --enable-static --enable-shared

pq-cryptocb:
# pq/ml_kem_cryptocb, pq/ml_dsa_cryptocb and pq/tls_cryptocb register a
# crypto callback that offloads the ML-KEM / ML-DSA operations, so they add
# --enable-cryptocb to the mlkem/dilithium flags their READMEs document.
# tls13 and the default ML-KEM hybrid groups (WOLFSSL_PQC_HYBRIDS) are on by
# default, which is what pq/tls_cryptocb needs.
flags: >-
--enable-cryptocb --enable-mlkem --enable-dilithium
--enable-experimental --enable-static --enable-shared

acert:
flags: "--enable-acert --enable-opensslextra --enable-rsapss --enable-static --enable-shared"

Expand Down Expand Up @@ -623,6 +633,29 @@ examples:
profile: pq
mode: check

- id: pq-ml-kem-cryptocb
path: pq/ml_kem_cryptocb
profile: pq-cryptocb
mode: check

- id: pq-ml-dsa-cryptocb
path: pq/ml_dsa_cryptocb
profile: pq-cryptocb
mode: check

- id: pq-tls-cryptocb
path: pq/tls_cryptocb
profile: pq-cryptocb
run:
- pair:
server: [./server-tls13-mlkem]
client: [./client-tls13-mlkem, 127.0.0.1]
stdin: "hello mlkem cryptocb\n"
server_exit: clean
# the server replies with a fixed string once the SecP256r1MLKEM768
# handshake completes, proving the ML-KEM key exchange carried data.
expect: "Server: I hear ya fa shizzle"

- id: pq-slh-dsa
path: pq/slh_dsa
profile: pq
Expand Down Expand Up @@ -1351,6 +1384,11 @@ examples:
mode: skip
reason: "shared helper (btle-sim.c) linked by btle/ecies and btle/tls; not an example"

- id: pq-cryptocb-common
path: pq
mode: skip
reason: "shared ML-KEM crypto-callback source (pq/mlkem-cryptocb.c) linked by pq/ml_kem_cryptocb and pq/tls_cryptocb; not an example"

- id: puf-host-test
path: puf/host_test
mode: skip
Expand Down
27 changes: 21 additions & 6 deletions .github/workflows/emulated.yml
Original file line number Diff line number Diff line change
Expand Up @@ -197,32 +197,47 @@ jobs:
pip install --quiet pyyaml

- name: Set up vcan0
id: vcan
run: |
set -euo pipefail
# vcan ships in linux-modules-extra and must match the running kernel exactly
sudo apt-get install -y "linux-modules-extra-$(uname -r)"
sudo modprobe can
sudo modprobe can-raw
sudo modprobe vcan
set -uo pipefail
# vcan ships in linux-modules-extra, which must match the running
# kernel. That package lags new runner-image kernels, so when it or
# the vcan module is unavailable, skip the can-bus run instead of
# failing the job.
if ! sudo apt-get install -y "linux-modules-extra-$(uname -r)"; then
echo "linux-modules-extra-$(uname -r) unavailable; skipping can-bus"
echo "ready=false" >> "$GITHUB_OUTPUT"
exit 0
fi
if ! { sudo modprobe can && sudo modprobe can-raw && sudo modprobe vcan; }; then
echo "vcan kernel modules unavailable; skipping can-bus"
echo "ready=false" >> "$GITHUB_OUTPUT"
exit 0
fi
set -e
sudo ip link add dev vcan0 type vcan
sudo ip link set vcan0 mtu 16 # 16 = classic CAN (72 for CAN FD)
sudo ip link set up vcan0
ip -details link show vcan0
echo "ready=true" >> "$GITHUB_OUTPUT"

- uses: ./.github/actions/setup-wolfssl
if: steps.vcan.outputs.ready == 'true'
id: wolfssl
with:
ref: ${{ matrix.wolfssl_ref }}
flags: --enable-all --enable-static --enable-shared
cflags: "-DWOLFSSL_ISOTP"

- name: Generate certs and build
if: steps.vcan.outputs.ready == 'true'
working-directory: can-bus
run: |
./generate_ssl.sh
make

- name: Run over vcan0
if: steps.vcan.outputs.ready == 'true'
working-directory: can-bus
run: |
set -euo pipefail
Expand Down
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,12 @@ pq/pqc_proxy/upgrade-proxy
pq/pqc_proxy/legacy-client
pq/pqc_proxy/pq-server

# PQ crypto callback examples
pq/ml_kem_cryptocb/ml_kem_cryptocb
pq/ml_dsa_cryptocb/ml_dsa_cryptocb
pq/tls_cryptocb/client-tls13-mlkem
pq/tls_cryptocb/server-tls13-mlkem

embedded/tls-client-server
embedded/tls-server-size
embedded/tls-sock-client
Expand Down
22 changes: 22 additions & 0 deletions pq/ml_dsa_cryptocb/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
CC = gcc

WOLFSSL_INSTALL_DIR = /usr/local

WOLFSSL_CFLAGS = -Wextra -Werror -Wall -I$(WOLFSSL_INSTALL_DIR)/include
WOLFSSL_LIBS = -L$(WOLFSSL_INSTALL_DIR)/lib -lm -lwolfssl

DEBUG_FLAGS = -g -DDEBUG

all: ml_dsa_cryptocb

ml_dsa_cryptocb: ml_dsa_cryptocb.c
Comment thread
dgarske marked this conversation as resolved.
Resolved
$(CC) -o $@ $^ $(WOLFSSL_CFLAGS) $(WOLFSSL_LIBS) $(DEBUG_FLAGS)

.PHONY: clean all check

clean:
rm -f *.o ml_dsa_cryptocb

check: ml_dsa_cryptocb
out=$$(./ml_dsa_cryptocb) && printf '%s' "$$out" | grep -q 'via crypto callback'
@echo "PASS: pq-ml-dsa-cryptocb checks"
52 changes: 52 additions & 0 deletions pq/ml_dsa_cryptocb/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Description

ML-DSA key generation, signing and verification routed through the wolfCrypt
crypto callback (cryptocb) interface. wolfSSL dispatches the signature
operations under `WC_ALGO_TYPE_PK` to a registered callback, which selects
ML-DSA with `WC_PQC_SIG_TYPE_MLDSA`.

The callback handles three operation types:

- `WC_PK_TYPE_PQC_SIG_KEYGEN` (`info->pk.pqc_sig_kg`) - generate a key pair.
- `WC_PK_TYPE_PQC_SIG_SIGN` (`info->pk.pqc_sign`) - sign a message.
- `WC_PK_TYPE_PQC_SIG_VERIFY` (`info->pk.pqc_verify`) - verify a signature.

The example signs and verifies with an empty context (FIPS 204 pure signing);
a pre-hash request falls back to software. The callback delegates back to the
wolfCrypt software implementation so it runs without hardware. A real device
replaces each case body with its own calls and keeps the private key on-chip.
It is registered with `wc_CryptoCb_RegisterDevice()`; for TLS, associate it
with a context using `wolfSSL_CTX_SetDevId()`.

Requires wolfSSL built with:

```sh
$ ./autogen.sh
$ ./configure --enable-cryptocb --enable-dilithium
$ make
$ sudo make install
$ sudo ldconfig
```

Build the example:

```sh
$ make
```

# Usage

```
$ ./ml_dsa_cryptocb
```

The ML-DSA key is initialized with a callback device id, so key generation,
signing and verification all dispatch to the callback. The program prints the
per-operation callback counts and confirms the signature verified.

# Related examples

- `pq/ml_kem_cryptocb` / `pq/tls_cryptocb` - the ML-KEM key-exchange counterpart,
standalone and in TLS 1.3.
- `pq/ml_dsa` - the same ML-DSA sign/verify in software, without a crypto callback.
- `ccb_vaultic` - a real secure-element crypto callback (SealSQ VaultIC).
Loading
Loading