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
169 changes: 169 additions & 0 deletions hsm/dtls_server/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
# Makefile for TLS/DTLS Server using wolfHSM for crypto operations
#
# This example demonstrates a server that offloads all cryptographic
# operations to a wolfHSM server running on the POSIX transport with
# DMA support. By default, DTLS (UDP) mode is used.
#
# Usage:
# make download_repos # Clone wolfSSL and wolfHSM repos
# make all # Build everything (wolfSSL, wolfHSM server, DTLS server)
# make run_hsm_server # Start wolfHSM server
# make run_dtls_server # Start wolfSSL DTLS server (this example)
# make run_client # Run the wolfSSL DTLS client
# make clean # Clean build artifacts
# make clean_repos # Remove cloned repositories

BIN = wh_server

WOLFSSL_DIR ?= ./wolfssl
WOLFHSM_DIR ?= ./wolfhsm
WOLFHSM_PORT_DIR = $(WOLFHSM_DIR)/port/posix
WOLFHSM_SERVER_DIR = $(WOLFHSM_DIR)/examples/posix/wh_posix_server

PROJECT_DIR = .
CONFIG_DIR = $(PROJECT_DIR)/config
BUILD_DIR = $(PROJECT_DIR)/Build

# Compiler settings
CC = gcc
CSTD = -std=c99
CFLAGS_EXTRA = -Werror -Wall -Wextra -ffunction-sections -fdata-sections
CFLAGS = $(CSTD) $(CFLAGS_EXTRA)

# Defines
DEF = -D_POSIX_C_SOURCE=200809L -DWOLFSSL_USER_SETTINGS -DWOLFHSM_CFG
DEF += -DWOLFHSM_CFG_DMA

# Includes
INC = -I$(PROJECT_DIR) -I$(CONFIG_DIR) -I$(WOLFSSL_DIR) -I$(WOLFHSM_DIR) -I$(WOLFHSM_PORT_DIR)

# Linker settings (platform-specific: darwin uses -dead_strip, others use --gc-sections)
OS_NAME := $(shell uname -s | tr A-Z a-z)
ifeq ($(OS_NAME),darwin)
LDFLAGS = -Wl,-dead_strip
else
LDFLAGS = -Wl,--gc-sections
endif
LIBS = -lc -lm

# Source files (wolfCrypt, wolfSSL, wolfHSM, port, project)
SRC_C = $(wildcard $(WOLFSSL_DIR)/wolfcrypt/src/*.c)
SRC_C += $(wildcard $(WOLFSSL_DIR)/src/*.c)
SRC_C += $(wildcard $(WOLFHSM_DIR)/src/*.c)
SRC_C += $(wildcard $(WOLFHSM_PORT_DIR)/*.c)
SRC_C += $(PROJECT_DIR)/server.c $(PROJECT_DIR)/server_io.c

# Debug support
ifeq ($(DEBUG),1)
CFLAGS += -ggdb -g3
LDFLAGS += -ggdb -g3
DEF += -DWOLFHSM_CFG_DEBUG
endif

# Object files
FILENAMES_C = $(notdir $(SRC_C))
OBJS_C = $(addprefix $(BUILD_DIR)/, $(FILENAMES_C:.c=.o))
vpath %.c $(dir $(SRC_C))
Comment on lines +64 to +66
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Building objects into a single directory using only $(notdir ...) risks object-name collisions (same basename from different directories), which can silently overwrite .o files and produce incorrect binaries. Use unique object paths (e.g., mirror source directories under Build/, or encode the source path into the object filename) so every source compiles to a distinct object file.

Copilot uses AI. Check for mistakes.

# Phony targets
.PHONY: all download_repos build_wolfssl build_wolfhsm_server build_app run_hsm_server run_dtls_server run_client clean clean_repos

# Default target
all: check_repos build_wolfssl build_wolfhsm_server build_app
@echo "Build complete. Run 'make run_hsm_server', 'make run_dtls_server', 'make run_client' in separate terminals."

# Clone repositories
download_repos:
@echo "=== Cloning repositories ==="
@if [ ! -d "$(WOLFSSL_DIR)" ]; then \
git clone --depth 1 https://github.com/wolfssl/wolfssl.git $(WOLFSSL_DIR); \
else \
echo "wolfssl already exists, skipping clone"; \
fi
@if [ ! -d "$(WOLFHSM_DIR)" ]; then \
git clone --depth 1 https://github.com/wolfssl/wolfhsm.git $(WOLFHSM_DIR); \
else \
echo "wolfhsm already exists, skipping clone"; \
fi

# Check that repos exist
check_repos:
@if [ ! -d "$(WOLFSSL_DIR)" ] || [ ! -d "$(WOLFHSM_DIR)" ]; then \
echo "Error: Repositories not found. Run 'make download_repos' first."; \
exit 1; \
fi

# Build wolfSSL (for example client)
build_wolfssl: check_repos
@echo "=== Building wolfSSL ==="
@if [ ! -f "$(WOLFSSL_DIR)/examples/server/server" ]; then \
cd $(WOLFSSL_DIR) && \
./autogen.sh && \
./configure --enable-dtls --enable-dtls13 --enable-ecc && \
make -j; \
else \
echo "wolfSSL already built, skipping"; \
fi

# Build wolfHSM POSIX server (with DMA for this example)
# Note: The wolfHSM server Makefile expects WOLFSSL_DIR relative to its location
# Server is at ./wolfhsm/examples/posix/wh_posix_server/
# wolfssl is at ./wolfssl/
# So from server: ../../../../wolfssl
build_wolfhsm_server: check_repos
@echo "=== Building wolfHSM server ==="
@if [ ! -f "$(WOLFHSM_SERVER_DIR)/Build/wh_posix_server.elf" ]; then \
$(MAKE) -C $(WOLFHSM_SERVER_DIR) clean || true; \
$(MAKE) -C $(WOLFHSM_SERVER_DIR) WOLFSSL_DIR=../../../../wolfssl DMA=1 -j; \
else \
echo "wolfHSM server already built, skipping"; \
fi

# Build DTLS server
build_app: $(BUILD_DIR) $(BUILD_DIR)/$(BIN).elf
@echo "DTLS server built: $(BUILD_DIR)/$(BIN).elf"

$(BUILD_DIR):
mkdir -p $(BUILD_DIR)

$(BUILD_DIR)/%.o: %.c
@echo "Compiling: $(notdir $<)"
$(CC) $(CFLAGS) $(DEF) $(INC) -c -o $@ $<

$(BUILD_DIR)/$(BIN).elf: $(OBJS_C)
@echo "Linking: $(notdir $@)"
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)

# Convenience targets for running each component in separate terminals

run_hsm_server: all
@echo "Starting wolfHSM server..."
@echo "Press Ctrl+C to stop"
@echo ""
$(WOLFHSM_SERVER_DIR)/Build/wh_posix_server.elf --type dma

run_dtls_server: all
@echo "Starting wolfSSL DTLS server (wolfHSM crypto offload)..."
@echo "Press Ctrl+C to stop"
@echo ""
$(BUILD_DIR)/$(BIN).elf -p 11111 -A $(WOLFSSL_DIR)/certs/client-cert.pem

run_client: all
cd $(WOLFSSL_DIR) && ./examples/client/client -u -v 4 -h 127.0.0.1 -p 11111

# Clean build artifacts
clean:
@echo "Cleaning build files..."
rm -rf $(BUILD_DIR)
@# Clean wolfHSM server build
@if [ -d "$(WOLFHSM_SERVER_DIR)" ]; then \
$(MAKE) -C $(WOLFHSM_SERVER_DIR) clean 2>/dev/null || true; \
fi
@# Clean wolfSSL build
@if [ -f "$(WOLFSSL_DIR)/Makefile" ]; then \
$(MAKE) -C $(WOLFSSL_DIR) clean 2>/dev/null || true; \
fi

clean_repos: clean
@echo "Removing cloned repositories"
rm -rf $(WOLFSSL_DIR) $(WOLFHSM_DIR)
219 changes: 219 additions & 0 deletions hsm/dtls_server/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
# TLS/DTLS Server with wolfHSM Crypto Offload

This example demonstrates a TLS/DTLS server that offloads cryptographic
operations to a wolfHSM server. By default, DTLS (UDP-based) is used, but
the code can be adapted for TLS (TCP-based) connections.

The wolfHSM server runs separately and communicates via the chosen transport.

## Architecture

```
+-------------------+ Shared Memory (DMA) +-------------------+
| | <-----------------------------> | |
| TLS/DTLS Server | Crypto Operations Request | wolfHSM Server |
| (This Example) | <-----------------------------> | (wh_posix_server)|
| | Crypto Operations Response | |
+-------------------+ +-------------------+
| |
| TLS/DTLS | Performs all
| | crypto ops:
v | - Key Exchange
+-------------------+ | - Signing
| TLS/DTLS Client | | - Encryption
| | | - Hashing
+-------------------+ +
```

## How It Works

1. **wolfHSM Server**: The `wh_posix_server` runs with `--type dma` to provide
crypto services over shared memory with DMA support.

2. **TLS/DTLS Server**: This example connects to the wolfHSM server as a client
and registers a crypto callback. All wolfSSL/wolfCrypt operations are
forwarded to the HSM.

3. **Crypto Offload**: When `wolfSSL_CTX_SetDevId()` is called with `WH_DEV_ID`,
wolfSSL routes crypto operations through the registered callback to the
wolfHSM server.

## Building

### Prerequisites

1. wolfSSL library built with crypto callback support
2. wolfHSM library with POSIX port

### Build Steps

```bash
# Build the server
cd examples/demo/dtls_server
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The README paths don’t match this PR’s directory layout (hsm/dtls_server/...), which will cause copy/paste build/run steps to fail. Update the cd ... instructions to the correct location for this demo, and fix the double-space typo in 'using wolfssl'.

Suggested change
cd examples/demo/dtls_server
cd hsm/dtls_server

Copilot uses AI. Check for mistakes.
make

# Build the wolfHSM POSIX server (if not already built)
cd ../../posix/wh_posix_server
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The README paths don’t match this PR’s directory layout (hsm/dtls_server/...), which will cause copy/paste build/run steps to fail. Update the cd ... instructions to the correct location for this demo, and fix the double-space typo in 'using wolfssl'.

Copilot uses AI. Check for mistakes.
make DMA=1
```

## Running

### Step 1: Start the wolfHSM Server

```bash
cd examples/posix/wh_posix_server
./Build/wh_posix_server.elf --type dma
```

You should see:
```
Example wolfHSM POSIX server built with wolfSSL version X.X.X
Using DMA with shared memory transport
Waiting for connection...
```

### Step 2: Start the Server

In a new terminal:

```bash
cd examples/demo/dtls_server
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The README paths don’t match this PR’s directory layout (hsm/dtls_server/...), which will cause copy/paste build/run steps to fail. Update the cd ... instructions to the correct location for this demo, and fix the double-space typo in 'using wolfssl'.

Copilot uses AI. Check for mistakes.
./Build/wh_server.elf
```

#### Command-Line Options

```
Usage: ./Build/wh_server.elf [options]

Options:
-A <file> CA certificate file (PEM or DER format)
If not specified, uses built-in test certificate
-c <file> Server certificate file (PEM or DER format)
-k <file> Server private key file (PEM or DER format)
-p <port> Port to listen on (default: 11111)
-h Show this help message
```

#### Examples

```bash
# Use default built-in certificates
./Build/wh_server.elf

# Use client-cert.pem from wolfssl bundle for example client to connect
./Build/wh_server.elf -A /path/to/wolfssl/certs/client-cert.pem

# Use custom certificates and port
./Build/wh_server.elf -A ca.pem -c server.pem -k server-key.pem -p 4433
```

You should see:
```
DTLS server starting on port 11111...
Connected to wolfHSM server successfully
Waiting for client on port 11111...
```

### Step 3: Connect a Client

In a third terminal:

```bash
# For DTLS (default mode) - using wolfssl with DTLS 1.3
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The README paths don’t match this PR’s directory layout (hsm/dtls_server/...), which will cause copy/paste build/run steps to fail. Update the cd ... instructions to the correct location for this demo, and fix the double-space typo in 'using wolfssl'.

Suggested change
# For DTLS (default mode) - using wolfssl with DTLS 1.3
# For DTLS (default mode) - using wolfssl with DTLS 1.3

Copilot uses AI. Check for mistakes.
./examples/examples/client -u -v 4
```

## Key Integration Points

### 1. Registering Crypto Callbacks

In `server.c`, we register the wolfHSM crypto callbacks:

```c
/* Register crypto callback for non-DMA operations */
wc_CryptoCb_RegisterDevice(WH_DEV_ID, wh_Client_CryptoCb, (void*)g_client);

/* Register crypto callback for DMA operations (larger data) */
wc_CryptoCb_RegisterDevice(WH_DEV_ID_DMA, wh_Client_CryptoCbDma, (void*)g_client);
```

### 2. Setting Device ID on wolfSSL Object

In `server_io.c`, we configure wolfSSL to use the HSM on the WOLFSSL_CTX object:

```c
wolfSSL_CTX_SetDevId(ctx, WH_DEV_ID);
```

### 3. DMA vs Non-DMA

- **WH_DEV_ID**: Uses standard message-based crypto operations. Suitable for
smaller data sizes.

- **WH_DEV_ID_DMA**: Uses DMA (Direct Memory Access) for data transfer.
More efficient for larger data like TLS record encryption.

## Configuration

### wolfSSL Configuration (`config/user_settings.h`)

Key settings for TLS/DTLS with wolfHSM:

```c
/* Enable DTLS 1.3 (for UDP mode) */
#define WOLFSSL_DTLS
#define WOLFSSL_DTLS13
#define WOLFSSL_TLS13

/* Enable crypto callbacks for wolfHSM */
#define WOLF_CRYPTO_CB

/* Hash DRBG for RNG */
#define HAVE_HASHDRBG
```

### wolfHSM Configuration (`config/wolfhsm_cfg.h`)

Key settings for wolfHSM client:

```c
/* Enable wolfHSM client */
#define WOLFHSM_CFG_ENABLE_CLIENT

/* Enable DMA transport */
#define WOLFHSM_CFG_DMA
```

## Troubleshooting

### "Failed to connect to wolfHSM server"

Make sure the `wh_posix_server` is running with `--type dma` before starting
the DTLS server.

### Handshake Failures

1. Check that both the wolfHSM server and DTLS server are built with the same
wolfSSL version.

2. Verify the shared memory name matches between client and server
(default: "wh_example_shm").

3. Enable verbose debugging:
```bash
make DEBUG_VERBOSE=1
```

## Adapting for TLS

To use TLS instead of DTLS:

1. In `server_io.c`, change the method from `wolfDTLS_server_method()` to
`wolfTLSv1_3_server_method()` or another TLS method.

2. Change the socket initialization from UDP to TCP (replace
`initialize_udp_socket()` with a TCP equivalent).

3. Remove the DTLS-specific peer address setup in `setup_ssl_accept()`.
Loading