Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
67ca3fc
Add nat20lib kernel module example and br environment.
werwurm Feb 11, 2026
4070f76
Fixup lint and add Makefiles to license checker.
werwurm Apr 29, 2026
de1ea2a
Make bootstrap executable
werwurm Apr 29, 2026
36bc192
Use prebuild toolchain and stop building qemu from scratch.
werwurm Apr 29, 2026
44c8f8f
address comments and also resolve circular dependency when using OVER…
werwurm Apr 29, 2026
6627ce3
Do not use relative paths
werwurm Apr 29, 2026
edbd436
Add module nat20device to linux examples.
werwurm Apr 28, 2026
2fd948f
Add nat20device to linux-kmod-build github action.
werwurm Apr 29, 2026
b9669af
nat20device fixups
werwurm Apr 30, 2026
d40b5bf
Add nat20crypto module to linux examples
werwurm Apr 28, 2026
49d4901
Set override SRCDIR for dependencies.
werwurm May 5, 2026
4b64988
Address comments.
werwurm May 5, 2026
b1899da
Merge branch 'refs/heads/werwurm/linux_example_nat20lib' into werwurm…
werwurm May 5, 2026
fee93e2
address comments
werwurm May 5, 2026
e5a7001
Serialize read and write access and document concurrency contracts.
werwurm May 5, 2026
b491dbb
Add macro for max instances
werwurm May 5, 2026
6062a0b
Merge branch 'refs/heads/werwurm/linux_example_nat20device' into werw…
werwurm May 5, 2026
1afed43
Update license in package config.
werwurm May 5, 2026
0eae0d8
tidy
werwurm May 5, 2026
47f9055
Add SECURITY.md and fix some issues.
werwurm May 5, 2026
6a47870
fix error handling contract.
werwurm May 6, 2026
54014fd
address comments
werwurm May 6, 2026
f645788
fixup KBuild
werwurm May 6, 2026
b621371
fixups
werwurm May 6, 2026
b7b57a6
fix error path
werwurm May 6, 2026
502f49c
fix non standard deterministic DSA construction
werwurm May 7, 2026
f5e6efd
Change shash initialization order
werwurm May 7, 2026
3ded408
typo
werwurm May 7, 2026
1957cd9
Merge branch 'werwurm/linux_example_nat20lib' into werwurm/linux_exam…
werwurm May 7, 2026
7fd4b5b
Merge branch 'main' into werwurm/linux_example_nat20device
werwurm May 7, 2026
424d872
Merge branch 'refs/heads/werwurm/linux_example_nat20device' into werw…
werwurm May 7, 2026
94a513c
address comments
werwurm May 7, 2026
49f3f1a
Merge branch 'main' into werwurm/linux_example_nat20crypto
werwurm May 7, 2026
f7b2bd3
Fix result size estimation.
werwurm May 8, 2026
c10d616
Fix underestimating size when overflowing after signing.
werwurm May 9, 2026
bf7e663
add test for underestimate after signing
werwurm May 9, 2026
13a4a4c
Merge branch 'werwurm/linux_example_nat20crypto' into werwurm/fix_cer…
werwurm May 9, 2026
f89cb70
Add nat20sw kernel module to linux examples.
werwurm Apr 28, 2026
f5285c6
address comments
werwurm May 11, 2026
8f306bb
Address comments.
werwurm May 11, 2026
080638f
Add libnat20 as buildroot package to the linux example.
werwurm Apr 28, 2026
fb0a11a
Merge branch 'werwurm/linux_example_nat20crypto' into werwurm/fix_cer…
werwurm May 12, 2026
0180dd9
Merge branch 'main' into werwurm/fix_certificate_size_estimates
werwurm May 12, 2026
d7d13bb
Merge branch 'werwurm/fix_certificate_size_estimates' into werwurm/li…
werwurm May 12, 2026
8808749
Merge branch 'main' into werwurm/linux_example_nat20sw
werwurm May 12, 2026
600e630
address comments
werwurm May 12, 2026
8b52e5f
Merge branch 'werwurm/linux_example_nat20sw' into werwurm/linux_examp…
werwurm May 12, 2026
1492110
address comments
werwurm May 12, 2026
dfc343c
Merge branch 'refs/heads/werwurm/linux_example_nat20sw' into werwurm/…
werwurm May 12, 2026
4be3210
Address comments
werwurm May 12, 2026
f3f0549
Make nat20sw.mk consistent
werwurm May 12, 2026
6bbee61
Merge branch 'refs/heads/werwurm/linux_example_nat20sw' into werwurm/…
werwurm May 12, 2026
7ffea18
address comments
werwurm May 13, 2026
42b2c9e
Merge branch 'werwurm/linux_example_nat20sw' into werwurm/linux_examp…
werwurm May 14, 2026
0612f25
Add nat20cli command line tool for nat20device.
werwurm Apr 29, 2026
b7a2f03
Address comments
werwurm May 14, 2026
47500a2
Add nat20 integration test suite for linux examples
werwurm May 14, 2026
8e3063f
Apply suggestions from code review
werwurm May 14, 2026
bb95742
address comments
werwurm May 14, 2026
2eac3fb
fix comma swallowing portability issue
werwurm May 15, 2026
b159fbb
Revert "Add nat20cli command line tool for nat20device."
werwurm May 15, 2026
2a5a8b6
Reapply "Add nat20cli command line tool for nat20device."
werwurm May 15, 2026
839b180
Merge branch 'werwurm/linux_example_nat20sw' into werwurm/linux_examp…
werwurm May 15, 2026
3cfbb32
Merge branch 'main' into werwurm/linux_example_libnat20
werwurm May 15, 2026
4e5acf5
polishing clitest
werwurm May 15, 2026
8739753
Merge branch 'werwurm/linux_example_libnat20' into werwurm/linux_exam…
werwurm May 16, 2026
9ddc860
Merge branch 'werwurm/linux_example_integration_test' into werwurm/li…
werwurm May 16, 2026
89d1814
Tidy test runner
werwurm May 16, 2026
b34c143
Merge branch 'werwurm/linux_example_integration_test' into werwurm/li…
werwurm May 16, 2026
967c20a
Add documentation for linux example
werwurm Apr 30, 2026
cee9a77
fixup module makefiles
werwurm May 16, 2026
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
1 change: 1 addition & 0 deletions .github/license-check/license-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"**/Kbuild",
"examples/linux/br_external/external.desc",
"examples/linux/**/Makefile",
"examples/linux/nat20cli/openssl_dice.cnf",
".clang-format",
".gitignore"
],
Expand Down
93 changes: 92 additions & 1 deletion .github/workflows/linux-kmod-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ jobs:
steps:
- uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b #v4.1.5

- name: Install Buildroot dependencies
- name: Install build and test dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
Expand All @@ -60,6 +60,7 @@ jobs:
git \
libncurses-dev \
python3 \
qemu-system-x86 \
rsync \
unzip \
wget
Expand Down Expand Up @@ -138,3 +139,93 @@ jobs:
find ${{ runner.temp }}/buildroot.build -name 'nat20sw.ko' | grep -q nat20sw.ko
echo "nat20sw.ko built successfully:"
find ${{ runner.temp }}/buildroot.build -name 'nat20sw.ko' -exec ls -la {} \;

- name: Build libnat20 userspace library
env:
LIBNAT20_OVERRIDE_SRCDIR: ${{ github.workspace }}
run: |
cd ${{ runner.temp }}/buildroot.build/buildroot
make libnat20-dirclean
make libnat20 -j $(( $(nproc) + 1 ))

- name: Verify libnat20 was produced
run: |
find ${{ runner.temp }}/buildroot.build -name 'libnat20.a' | grep -q libnat20.a
echo "libnat20.a built successfully:"
find ${{ runner.temp }}/buildroot.build -name 'libnat20.a' -exec ls -la {} \;

- name: Build nat20cli userspace cli tool
env:
LIBNAT20_OVERRIDE_SRCDIR: ${{ github.workspace }}
NAT20CLI_OVERRIDE_SRCDIR: ${{ github.workspace }}
run: |
cd ${{ runner.temp }}/buildroot.build/buildroot
make nat20cli-dirclean
make nat20cli -j $(( $(nproc) + 1 ))

- name: Verify nat20cli was produced
run: |
find ${{ runner.temp }}/buildroot.build -name 'nat20cli' | grep -q nat20cli
echo "nat20cli built successfully:"
find ${{ runner.temp }}/buildroot.build -name 'nat20cli' -exec ls -la {} \;

- name: Build rootfs image
env:
NAT20LIB_OVERRIDE_SRCDIR: ${{ github.workspace }}
NAT20DEVICE_OVERRIDE_SRCDIR: ${{ github.workspace }}
NAT20CRYPTO_OVERRIDE_SRCDIR: ${{ github.workspace }}
NAT20SW_OVERRIDE_SRCDIR: ${{ github.workspace }}
LIBNAT20_OVERRIDE_SRCDIR: ${{ github.workspace }}
NAT20CLI_OVERRIDE_SRCDIR: ${{ github.workspace }}
NAT20TEST_OVERRIDE_SRCDIR: ${{ github.workspace }}
run: make -C ${{ runner.temp }}/buildroot.build/buildroot -j $(( $(nproc) + 1 ))

- name: Run integration tests in QEMU
timeout-minutes: 5
run: |
BUILDROOT_DIR="${{ runner.temp }}/buildroot.build/buildroot"
KERNEL="${BUILDROOT_DIR}/output/images/bzImage"
ROOTFS="${BUILDROOT_DIR}/output/images/rootfs.ext2"

qemu-system-x86_64 \
-M pc \
-kernel "${KERNEL}" \
-drive file="${ROOTFS}",if=virtio,format=raw \
-append "rootwait root=/dev/vda console=ttyS0 init=/usr/bin/nat20test_qemu_init.sh" \
-nographic \
-no-reboot \
-net none \
2>&1 | tee qemu_output.log

if grep -q "INTEGRATION_TESTS_PASSED" qemu_output.log; then
echo "Integration tests passed."
else
echo "Integration tests failed. QEMU output:"
cat qemu_output.log
exit 1
fi

- name: Run nat20cli tests in QEMU
timeout-minutes: 5
run: |
BUILDROOT_DIR="${{ runner.temp }}/buildroot.build/buildroot"
KERNEL="${BUILDROOT_DIR}/output/images/bzImage"
ROOTFS="${BUILDROOT_DIR}/output/images/rootfs.ext2"

qemu-system-x86_64 \
-M pc \
-kernel "${KERNEL}" \
-drive file="${ROOTFS}",if=virtio,format=raw \
-append "rootwait root=/dev/vda console=ttyS0 init=/usr/bin/nat20cli_qemu_init.sh" \
-nographic \
-no-reboot \
-net none \
2>&1 | tee qemu_output.log

if grep -q "NAT20CLI_TESTS_PASSED" qemu_output.log; then
echo "NAT20CLI tests passed."
else
echo "NAT20CLI tests failed. QEMU output:"
cat qemu_output.log
exit 1
fi
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,3 @@ build/
cmake_install.cmake
compile_commands.json
html/
nat20test
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,15 @@ make nat20_docs
Open the documentation by pointing your browser to `html/index.html` in your
build directory.

## Examples

### Linux DICE kernel modules

The `examples/linux/` directory contains a complete Linux kernel module
implementation of a software DICE node, including a userspace CLI tool and a
Buildroot-based build environment targeting QEMU. See
[examples/linux/README.md](examples/linux/README.md) for details.

## API Reference

The API references is generated from the main branch using doxygen and deployed
Expand Down
132 changes: 132 additions & 0 deletions examples/linux/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
# Linux DICE Example

This directory contains a set of Linux kernel modules and a userspace CLI tool
that together implement a software DICE node using libnat20.

## Architecture

The example is structured as four kernel modules with the following dependency
chain:

```
nat20sw ──► nat20crypto ──► nat20lib
nat20device ──►
```

### nat20lib

A kernel module wrapper around the core libnat20 C library. It compiles all
core library sources (CBOR, COSE, CWT, X.509, HKDF, service dispatch) into a
single `.ko` and re-exports their symbols via `EXPORT_SYMBOL()` so that other
kernel modules can use them.

### nat20crypto

Implements the libnat20 crypto interface (`n20_crypto_context_t`) using the
Linux kernel's crypto API. Provides ECDSA signing (P-256, P-384), HKDF key
derivation, and SHA-2 hashing — all in kernel space.

### nat20device

A generic character device framework for DICE services. On load it allocates
the `nat20` device class. Backend modules (like `nat20sw`) register via
`nat20device_register_driver()`, which creates:

- `/dev/nat20<N>` — a character device for DICE service requests (write a CBOR
request, read the CBOR response).
- `/sys/kernel/security/nat20<N>/dice_chain` — a read-only securityfs file
exposing the boot-time DICE certificate chain.

### nat20sw

A concrete software DICE node that wires `nat20lib`, `nat20crypto`, and
`nat20device` together. On load it derives a UDS from a hardcoded passphrase
(for demonstration purposes only), issues a self-signed X.509 certificate, and
registers itself with the `nat20device` framework.

### nat20cli

A userspace command-line tool that communicates with the DICE service via
`/dev/nat200`. It can issue CDI certificates, ECA certificates, and advance
the DICE layer via the `promote` command.

## The `dice_chain` securityfs interface

Each registered nat20device driver instance exposes a `dice_chain` file at
`/sys/kernel/security/nat20<N>/dice_chain`. This file contains the DICE
certificate chain constructed during bootup, encoded as a CBOR
indefinite-length array.

### Encoding

The file contains a single CBOR indefinite-length array (`0x9f ... 0xff`).
Each element in the array is one of the following CBOR-tagged values:

| CBOR tag | Content | Description |
|----------|---------|-------------|
| `#6.80150(bstr)` | DER-encoded X.509 certificate | An X.509 certificate, typically with the Open DICE Input extension (OID `1.3.6.1.4.1.11129.2.1.24`). |
| `#6.18(COSE_Sign1)` | COSE_Sign1 with CWT payload | A COSE certificate as specified by the Open DICE profile or a similar custom DICE profile. |
| `#8.80152(COSE_Key)` | COSE_Key | A public key. |

### Ordering and semantics

- The first element represents the root device identity key. It may be a
self-signed certificate, a CA-signed certificate, or a bare public key
(`#8.80152`).
- A benign implementation orders the remaining certificates from root to leaf.
- The chain only contains certificates generated during bootup. Userspace is
responsible for managing additional CDI certificates issued via the
`/dev/nat20<N>` character device.

## Building with Buildroot

The `br_external/` directory provides a Buildroot external tree for building
all components targeting a QEMU x86_64 virtual machine.

```sh
# Bootstrap the Buildroot environment (build directory must be outside the repo)
BUILDROOT_DIR=/path/to/buildroot.build
examples/linux/br_external/bootstrap.sh qemu $BUILDROOT_DIR

# Build everything
cd $BUILDROOT_DIR/buildroot
make
```

### Local development
The bootstrap script installs a file `envsetup.sh` in `$BUILDROOT_DIR`
which sets the `*_OVERRIDE_SRCDIR`s for all of the packages nat20* etc.,
and defines helper functions for rebuilding and running the result in
qemu.

```
# Source the environment
cd $BUILDROOT_DIR
. envsetup.sh

# Rebuild a package and the rootfs, this is equivalent to
# pushd $BUILDROOT_DIR/buildroot
# make nat20sw-rebuild all
# popd
brrebuild nat20sw

# Rebuild all packages and the rootfs
brrebuild all

# Run the resulting rootfs and kernel in qemu
run-qemu

# Run the nat20cli test in qemu and shut down the emulator
run-nat20cli-test

# Run the nat20test integration test in qemu and sht down the emulator
run-nat20test-test
```

### Caveat - `bootstrap.sh`
The bootstrap script is usefull for setting up the development environment
once, but it cannot keep the build root environment in sync with the upstream
repository. When pulling the upstream repository and changes where made to
`envsetup.sh`, `bootstrap.sh`, or the buildroot config, it may be necessary
to bootstrap a new environment. A savvy user may track the changes and manually
update the environment to save 30 minutes rebuilding the build root environment.
3 changes: 3 additions & 0 deletions examples/linux/br_external/Config.in
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@
# along with this program; if not, see
# <https://www.gnu.org/licenses/>.

source "$BR2_EXTERNAL_NAT20_PATH/package/nat20cli/Config.in"
source "$BR2_EXTERNAL_NAT20_PATH/package/nat20crypto/Config.in"
source "$BR2_EXTERNAL_NAT20_PATH/package/nat20device/Config.in"
source "$BR2_EXTERNAL_NAT20_PATH/package/nat20sw/Config.in"
source "$BR2_EXTERNAL_NAT20_PATH/package/nat20lib/Config.in"
source "$BR2_EXTERNAL_NAT20_PATH/package/libnat20/Config.in"
source "$BR2_EXTERNAL_NAT20_PATH/package/nat20test/Config.in"
2 changes: 1 addition & 1 deletion examples/linux/br_external/bootstrap.sh
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ pushd ${LIBNAT20_BR_BUILD_DIR}

echo "LIBNAT20_BR_BUILD_DIR=${LIBNAT20_BR_BUILD_DIR}" | tee .env
echo "LIBNAT20_ROOT=${LIBNAT20_ROOT}" | tee -a .env
echo "LIBNAT20_PROJECT=${PROJECT}" | tee -a .env

cp ${LIBNAT20_ROOT}/examples/linux/br_external/utils/envsetup.sh ./

Expand All @@ -109,7 +110,6 @@ git clone --depth 1 --branch "2025.08.1" https://gitlab.com/buildroot.org/buildr
case "$PROJECT" in
qemu)
cp ${LIBNAT20_ROOT}/examples/linux/br_external/configs/qemu_br_defconfig buildroot/.config
cp ${LIBNAT20_ROOT}/examples/linux/br_external/run-qemu.sh ./
;;
esac

Expand Down
3 changes: 3 additions & 0 deletions examples/linux/br_external/configs/qemu_br_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -3976,7 +3976,10 @@ BR2_TARGET_UBOOT_CUSTOM_PATCH_DIR=""
#
# Provides NAT20 related packages.
#
BR2_PACKAGE_NAT20CLI=y
BR2_PACKAGE_NAT20CRYPTO=y
BR2_PACKAGE_NAT20DEVICE=y
BR2_PACKAGE_NAT20SW=y
BR2_PACKAGE_NAT20LIB=y
BR2_PACKAGE_LIBNAT20=y
BR2_PACKAGE_NAT20TEST=y
39 changes: 39 additions & 0 deletions examples/linux/br_external/package/libnat20/Config.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Copyright 2026 Aurora Operations, Inc.
#
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0
#
# This work is dual licensed.
# You may use it under Apache-2.0 or GPL-2.0 at your option.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# OR
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see
# <https://www.gnu.org/licenses/>.

config BR2_PACKAGE_LIBNAT20
bool "libnat20"
help
Add the libnat20 DICE library
Loading
Loading