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
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,9 @@ set(LIBNAT20_DOC_PAGES
# Add additional input files for doxygen here.
README.md
CONTRIBUTING.md
examples/linux/README_linux.md
examples/linux/nat20crypto/SECURITY.md
src/service/DICE_SERVICE.md
)

set(LIBNAT20_PUB_CRYPTO_BSSL_HEADERS
Expand Down Expand Up @@ -686,6 +689,7 @@ if (NAT20_WITH_DOCS)

set(DOXYGEN_USE_MDFILE_AS_MAINPAGE README.md)
set(DOXYGEN_MACRO_EXPANSION YES)
set(DOXYGEN_EXTRACT_STATIC YES)

doxygen_add_docs(nat20_docs
${LIBNAT20_PUB_HEADERS}
Expand Down
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
[README_linux.md](examples/linux/README_linux.md) for details.

## API Reference

The API references is generated from the main branch using doxygen and deployed
Expand Down
151 changes: 151 additions & 0 deletions examples/linux/README_linux.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
# 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:

@dot
digraph mod_deps {
rankdir=LR;
node [shape=record];
nat20sw -> nat20crypto;
nat20sw -> nat20device;
nat20crypto -> nat20lib;
nat20device -> nat20lib;
}
@enddot

### nat20lib

A kernel module wrapper around the core libnat20 C library. It compiles all
core library sources, i.e,
- certificate rendering primitives for X.509 and COSE_Sign1 wrapped CWTs,
- DICE key derivation procedures including
- CDI derivation,
- CDI_ID computation,
- AKDF key pare generation,
- issuing and signing of CDI attestaiton and ECA certificates,
- service messages (un)marshaling and dispatch, and
- gnostic node service implementation

into a kernel obejct (`.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.

\warning The eliptic curve crypto (ECC) implementaiton in this module is not ready
for production see [Security Assessment - nat20crypto](examples/linux/nat20crypto/SECURITY.md)
for details.

### 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.
23 changes: 7 additions & 16 deletions examples/linux/nat20crypto/SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,9 @@ key information through timing side channels.

## Key Material Leak Analysis

### Addressed

- **`nat20crypto_sign`** — stack buffers `z`, `k`, `k_inv`, `rs` are wiped via
`memzero_explicit` on all exit paths. This covers the nonce, the inverted
nonce, the byte-swapped private key (in `k_inv` via the `key_bytes` alias),
and intermediate signature values.
- **`nat20crypto_key_destroy`** — uses `memzero_explicit` before `kfree`.
- **`nat20crypto_make_secret`** — the input `secret_in` buffer is caller-owned;
the output key is heap-allocated and properly zeroed on free.

### Outstanding issues

#### `n20_rfc6979_k_generation` internal state
#### n20_rfc6979_k_generation internal state

This function (from nat20lib) uses HMAC internally with the private key as
input. Whether its internal buffers are zeroed depends on its implementation.
Expand All @@ -34,27 +24,28 @@ Out of scope for this module but noted as a dependency.
In a DICE boot-time context where signing happens once during module init with
no concurrent attacker (single-threaded init, no network, no user interaction),
timing side channels are not practically exploitable. For a general-purpose
signing oracle accessible from userspace, the issues below would be exploitable.
signing oracle accessible from userspace, i.e., the embedded-CA functionality,
the issues below would be exploitable.

### High risk

#### `vli_mod_inv` — variable-time modular inverse
#### vli_mod_inv — variable-time modular inverse

The kernel's `vli_mod_inv` computes the modular inverse of `k` using a binary
extended GCD with data-dependent branches and loop counts. The number of
iterations depends on the value of `k`, leaking nonce information through
timing. Partial nonce knowledge enables private key recovery via lattice
attacks.

#### `ecc_make_pub_key` — variable-time point multiplication
#### ecc_make_pub_key — variable-time point multiplication

The kernel's ECC point multiplication uses a double-and-add algorithm. Older
kernels (pre-6.10) use a naive implementation with data-dependent
doublings/additions, leaking the scalar `k` through timing.

### Medium risk

#### `vli_mod_mult_slow` — conditional subtraction
#### vli_mod_mult_slow — conditional subtraction

The kernel's `vli_mod_mult_slow` is a shift-and-add modular multiplication.
The loop count is constant, but the conditional subtraction after each shift
Expand Down Expand Up @@ -82,7 +73,7 @@ about the private key.
The kernel's SHA implementations are generally constant-time for the
compression function. HMAC processes fixed-size blocks. Low timing risk.

#### `ecc_swap_digits` / `memcpy` / simple copies
#### ecc_swap_digits / memcpy / simple copies

These process a fixed number of bytes regardless of value. Constant-time.

Expand Down
2 changes: 1 addition & 1 deletion include/nat20/crypto/nat20/crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ extern n20_error_t n20_crypto_nat20_open(n20_crypto_digest_context_t** ctx_out);
* @brief Close the NAT20 cryptographic context.
*
* This function closes and frees the resources associated with the
* context @ref ctx_out.
* context @p ctx_out.
*
* In the current implementation this is a no-op, as the context
* is a singleton. But this may change in the future, and must
Expand Down
6 changes: 6 additions & 0 deletions include/nat20/crypto/nat20/rfc6979.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,13 @@ extern "C" {
* index always has the lowest significance.
*/
struct n20_bn_s {
/**
* @brief The number of words in the big number.
*/
size_t word_count;
/**
* @brief The array of words representing the big number.
*/
uint32_t* words;
};

Expand Down
5 changes: 4 additions & 1 deletion include/nat20/endian.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@
* <https://www.gnu.org/licenses/>.
*/

/** @file Homogeneous Endian definitions for various environments. */
/**
* @file endian.h
* @brief Homogeneous Endian definitions for various environments.
*/

#pragma once

Expand Down
5 changes: 4 additions & 1 deletion include/nat20/limits.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@
* <https://www.gnu.org/licenses/>.
*/

/** @file Homogeneous Limits definitions for various environments. */
/**
* @file limits.h
* @brief Homogeneous Limits definitions for various environments.
*/

#pragma once

Expand Down
6 changes: 3 additions & 3 deletions include/nat20/service/gnostic.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ extern "C" {
*
* The service node state includes a pointer to a crypto context and the minimal CDI
* that the service node can use to derive other CDIs. The service operations
* for this implementation are defined in @ref src/service/gnostic.c, and is based
* on the DICE functionality implemented in @ref src/core/functionality.c.
* for this implementation are defined in src/service/gnostic.c, and is based
* on the DICE functionality implemented in src/core/functionality.c.
* The supported operations include CDI promotion, issuing CDI certificates,
* issuing ECA certificates, issuing ECA end-entity certificates, signing with ECA
* end-entity keys.
Expand Down Expand Up @@ -100,7 +100,7 @@ typedef struct n20_gnostic_node_state_s n20_gnostic_node_state_t;
/**
* @brief The service operations for the Gnostic Stateless service implementation.
*
* This symbol is defined in @ref src/service/gnostic.c and represents
* This symbol is defined in src/service/gnostic.c and represents
* a fully initialized n20_service_ops_t structure that can be used to
* implement a service node with the Gnostic Stateless implementation.
*/
Expand Down
Loading