Skip to content

Commit c586428

Browse files
authored
wolfHSM: add DTLS client example that uses HSM as cryptographic back end (#555)
* wolfHSM: add DTLS client that uses HSM as cryptographic backend * address reviewer's comment * dtls client improvements
1 parent dc6a012 commit c586428

7 files changed

Lines changed: 856 additions & 0 deletions

File tree

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,16 @@ Please see the [utasker/README.md](utasker/README.md) for further usage and
390390
details.
391391

392392

393+
<br />
394+
395+
#### hsm (wolfHSM Examples)
396+
397+
This directory contains examples demonstrating wolfSSL integration with wolfHSM,
398+
a portable Hardware Security Module framework.
399+
400+
Please see the [hsm/README.md](hsm/README.md) for further details.
401+
402+
393403
<br />
394404

395405
#### uefi-static (wolfCrypt UEFI application Example)

hsm/README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# wolfHSM Examples
2+
3+
Examples demonstrating wolfSSL integration with [wolfHSM](https://github.com/wolfssl/wolfhsm),
4+
a portable Hardware Security Module (HSM) framework.
5+
6+
## Examples
7+
8+
### DTLS Client (`dtls_client/`)
9+
10+
DTLS client with HSM-backed cryptography. Private keys stay on the HSM.
11+
12+
Quick start (from the `wolfssl-examples` repository root):
13+
```bash
14+
cd hsm/dtls_client
15+
make download_repos
16+
make all
17+
# Then run each component in separate terminals (see README)
18+
```
19+
20+
See [dtls_client/README.md](dtls_client/README.md) for details.
21+
22+
## Support
23+
24+
For questions please email support@wolfssl.com

hsm/dtls_client/Makefile

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
# wolfHSM DTLS Client Example
2+
#
3+
# Usage:
4+
# make download_repos # Clone wolfSSL and wolfHSM repos
5+
# make all # Build everything (wolfSSL server, wolfHSM server, client)
6+
# make run_hsm_server # Start wolfHSM server
7+
# make run_dtls_server # Start wolfSSL DTLS server
8+
# make run_client # Run the DTLS client
9+
# make clean # Clean build artifacts
10+
# make clean_repos # Remove cloned repositories
11+
12+
BIN = wh_dtls_client
13+
14+
WOLFSSL_DIR ?= ./wolfssl
15+
WOLFHSM_DIR ?= ./wolfhsm
16+
WOLFHSM_PORT_DIR = $(WOLFHSM_DIR)/port/posix
17+
WOLFHSM_SERVER_DIR = $(WOLFHSM_DIR)/examples/posix/wh_posix_server
18+
19+
PROJECT_DIR = .
20+
BUILD_DIR = $(PROJECT_DIR)/Build
21+
22+
# Compiler settings
23+
CC = gcc
24+
CSTD = -std=c99
25+
CFLAGS_EXTRA = -Werror -Wall -Wextra -ffunction-sections -fdata-sections
26+
CFLAGS = $(CSTD) $(CFLAGS_EXTRA)
27+
DEF = -D_POSIX_C_SOURCE=200809L -DWOLFSSL_USER_SETTINGS -DWOLFHSM_CFG
28+
DEF += -DWC_USE_DEVID=0x5748534D
29+
# Several wolfSSL sources (asn_orig.c, pk_ec.c, ssl_*.c, ...) are meant to be
30+
# #included by a parent translation unit and #warning when built standalone, which
31+
# -Werror turns into an error. This macro silences only those, leaving genuine
32+
# configuration warnings (e.g. random.c's insecure-seed warning) still fatal.
33+
DEF += -DWOLFSSL_IGNORE_FILE_WARN
34+
35+
INC = -I$(PROJECT_DIR) -I$(WOLFSSL_DIR) -I$(WOLFHSM_DIR) -I$(WOLFHSM_PORT_DIR)
36+
37+
# Linker settings
38+
LDFLAGS = -Wl,--gc-sections
39+
LIBS = -lm -lpthread
40+
41+
# Source files (wolfCrypt, wolfSSL, wolfHSM, port, project)
42+
WOLFCRYPT_SRC := $(wildcard $(WOLFSSL_DIR)/wolfcrypt/src/*.c)
43+
SRC_C = $(filter-out %/evp.c %/misc.c,$(WOLFCRYPT_SRC))
44+
WOLFSSL_SRC := $(wildcard $(WOLFSSL_DIR)/src/*.c)
45+
SRC_C += $(filter-out %/bio.c %/conf.c %/pk.c %/ssl_asn1.c %/ssl_bn.c %/ssl_certman.c %/ssl_crypto.c %/ssl_load.c %/ssl_misc.c %/ssl_p7p12.c %/ssl_sess.c %/ssl_sk.c %/x509.c %/x509_str.c,$(WOLFSSL_SRC))
46+
SRC_C += $(wildcard $(WOLFHSM_DIR)/src/*.c)
47+
SRC_C += $(wildcard $(WOLFHSM_PORT_DIR)/*.c)
48+
SRC_C += $(wildcard $(PROJECT_DIR)/*.c)
49+
50+
# Debug support
51+
ifeq ($(DEBUG),1)
52+
CFLAGS += -ggdb -g3
53+
LDFLAGS += -ggdb -g3
54+
DEF += -DWOLFHSM_CFG_DEBUG
55+
endif
56+
57+
# Object files
58+
FILENAMES_C = $(notdir $(SRC_C))
59+
OBJS_C = $(addprefix $(BUILD_DIR)/, $(FILENAMES_C:.c=.o))
60+
vpath %.c $(dir $(SRC_C))
61+
62+
# Phony targets
63+
.PHONY: all download_repos check_repos build_wolfssl build_wolfhsm_server build_app run_hsm_server run_dtls_server run_client clean clean_repos
64+
65+
# Default target
66+
all: check_repos build_wolfssl build_wolfhsm_server build_app
67+
@echo "Build complete. See README.md for usage instructions."
68+
69+
# Clone repositories
70+
download_repos:
71+
@echo "=== Cloning repositories ==="
72+
@if [ ! -d "$(WOLFSSL_DIR)" ]; then \
73+
git clone --depth 1 https://github.com/wolfssl/wolfssl.git $(WOLFSSL_DIR); \
74+
else \
75+
echo "wolfssl already exists, skipping clone"; \
76+
fi
77+
@if [ ! -d "$(WOLFHSM_DIR)" ]; then \
78+
git clone --depth 1 https://github.com/wolfssl/wolfhsm.git $(WOLFHSM_DIR); \
79+
else \
80+
echo "wolfhsm already exists, skipping clone"; \
81+
fi
82+
83+
# Check that repos exist
84+
check_repos:
85+
@if [ ! -d "$(WOLFSSL_DIR)" ] || [ ! -d "$(WOLFHSM_DIR)" ]; then \
86+
echo "Error: Repositories not found. Run 'make download_repos' first."; \
87+
exit 1; \
88+
fi
89+
90+
# Build wolfSSL
91+
# Note: The DTLS client uses its own user_settings.h to build wolfSSL statically,
92+
# so this configure is only for the wolfSSL example server/client binaries.
93+
build_wolfssl: check_repos
94+
@echo "=== Building wolfSSL ==="
95+
@if [ ! -f "$(WOLFSSL_DIR)/examples/server/server" ]; then \
96+
cd $(WOLFSSL_DIR) && \
97+
./autogen.sh && \
98+
./configure --enable-dtls --enable-dtls13 --enable-ecc && \
99+
make -j; \
100+
else \
101+
echo "wolfSSL already built, skipping"; \
102+
fi
103+
104+
# Build wolfHSM POSIX server
105+
# Note: The wolfHSM server Makefile expects WOLFSSL_DIR relative to its location
106+
# Server is at ./wolfhsm/examples/posix/wh_posix_server/
107+
# wolfssl is at ./wolfssl/
108+
# So from server: ../../../../wolfssl
109+
build_wolfhsm_server: check_repos
110+
@echo "=== Building wolfHSM server ==="
111+
@if [ ! -f "$(WOLFHSM_SERVER_DIR)/Build/wh_posix_server.elf" ]; then \
112+
$(MAKE) -C $(WOLFHSM_SERVER_DIR) clean || true; \
113+
$(MAKE) -C $(WOLFHSM_SERVER_DIR) WOLFSSL_DIR=../../../../wolfssl -j; \
114+
else \
115+
echo "wolfHSM server already built, skipping"; \
116+
fi
117+
118+
# Build DTLS client
119+
build_app: $(BUILD_DIR)/$(BIN).elf
120+
@echo "DTLS client built: $(BUILD_DIR)/$(BIN).elf"
121+
122+
$(BUILD_DIR):
123+
mkdir -p $(BUILD_DIR)
124+
125+
$(BUILD_DIR)/%.o: %.c | $(BUILD_DIR)
126+
@echo "Compiling: $(notdir $<)"
127+
$(CC) $(CFLAGS) $(DEF) $(INC) -c -o $@ $<
128+
129+
$(BUILD_DIR)/$(BIN).elf: $(OBJS_C) | $(BUILD_DIR)
130+
@echo "Linking: $(notdir $@)"
131+
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
132+
133+
# Convenience targets for running each component in separate terminals
134+
135+
run_hsm_server: all
136+
@echo "Starting wolfHSM server..."
137+
@echo "Press Ctrl+C to stop"
138+
@echo ""
139+
$(WOLFHSM_SERVER_DIR)/Build/wh_posix_server.elf --type tcp \
140+
--key $(WOLFSSL_DIR)/certs/ecc-client-key.der \
141+
--id 1 --client 12
142+
143+
run_dtls_server: all
144+
@echo "Starting wolfSSL DTLS server..."
145+
@echo "Press Ctrl+C to stop"
146+
@echo ""
147+
cd $(WOLFSSL_DIR) && ./examples/server/server -u -v d \
148+
-c ./certs/server-ecc.pem \
149+
-k ./certs/ecc-key.pem \
150+
-A ./certs/client-ecc-cert.pem \
151+
-p 11111 -i
152+
153+
run_client: all
154+
$(BUILD_DIR)/$(BIN).elf 127.0.0.1
155+
156+
# Clean build artifacts
157+
clean:
158+
@echo "Cleaning build files"
159+
rm -rf $(BUILD_DIR)
160+
@# Clean wolfHSM server build
161+
@if [ -d "$(WOLFHSM_SERVER_DIR)" ]; then \
162+
$(MAKE) -C $(WOLFHSM_SERVER_DIR) clean 2>/dev/null || true; \
163+
fi
164+
@# Clean wolfSSL build
165+
@if [ -f "$(WOLFSSL_DIR)/Makefile" ]; then \
166+
$(MAKE) -C $(WOLFSSL_DIR) clean 2>/dev/null || true; \
167+
fi
168+
169+
clean_repos: clean
170+
@echo "Removing cloned repositories"
171+
rm -rf $(WOLFSSL_DIR) $(WOLFHSM_DIR)

hsm/dtls_client/README.md

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# wolfHSM DTLS Client Example
2+
3+
Demonstrates a DTLS client using wolfHSM for cryptographic operations.
4+
All private key operations are performed on the HSM - keys never leave
5+
the secure environment.
6+
The example uses wolfHSM posix server for HSM communication/simulation.
7+
8+
9+
## Quick Start
10+
11+
### Build
12+
```bash
13+
make download_repos # Clone repos (first time only)
14+
make all # Build everything
15+
```
16+
17+
### Run (3 separate terminals)
18+
19+
**Terminal 1** - Start wolfHSM posix server:
20+
```bash
21+
make run_hsm_server
22+
```
23+
24+
**Terminal 2** - Start DTLS server:
25+
```bash
26+
make run_dtls_server
27+
```
28+
29+
**Terminal 3** - Run client:
30+
```bash
31+
make run_client
32+
```
33+
34+
## Using Existing Repositories
35+
36+
```bash
37+
make WOLFSSL_DIR=/path/to/wolfssl WOLFHSM_DIR=/path/to/wolfhsm all
38+
```
39+
40+
## Architecture
41+
42+
```
43+
+------------------+ TCP +------------------+
44+
| DTLS Client |<------------>| wolfHSM Server |
45+
| | | (crypto ops) |
46+
+--------+---------+ +------------------+
47+
| UDP/DTLS
48+
v
49+
+------------------+
50+
| DTLS Server |
51+
| (application) |
52+
+------------------+
53+
```
54+
55+
## Makefile Targets
56+
57+
| Target | Description |
58+
|--------|-------------|
59+
| `download_repos` | Clone wolfSSL and wolfHSM |
60+
| `all` | Build everything (default) |
61+
| `run_hsm_server` | Start wolfHSM server (Terminal 1) |
62+
| `run_dtls_server` | Start wolfSSL DTLS server (Terminal 2) |
63+
| `run_client` | Run the DTLS client (Terminal 3) |
64+
| `clean` | Clean build artifacts |
65+
| `clean_repos` | Remove cloned repositories |
66+
67+
## Debug Build
68+
69+
```bash
70+
make clean
71+
make DEBUG=1
72+
```

hsm/dtls_client/user_settings.h

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/* user_settings.h
2+
*
3+
* Copyright (C) 2006-2026 wolfSSL Inc.
4+
*
5+
* This file is part of wolfSSL. (formerly known as CyaSSL)
6+
*
7+
* wolfSSL is free software; you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation; either version 2 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* wolfSSL is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with this program; if not, write to the Free Software
19+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
20+
*/
21+
22+
#ifndef USER_SETTINGS_H_
23+
#define USER_SETTINGS_H_
24+
25+
26+
/* POSIX system headers */
27+
#define HAVE_SYS_TIME_H
28+
29+
/** wolfHSM Client required settings */
30+
/* CryptoCB support - required for offloading crypto to HSM */
31+
#define WOLF_CRYPTO_CB
32+
#define HAVE_ANONYMOUS_INLINE_AGGREGATES 1
33+
34+
/* PK callbacks - required for TLS-level HSM key operations */
35+
#define HAVE_PK_CALLBACKS
36+
37+
/* Enable DTLS support */
38+
#define WOLFSSL_DTLS
39+
#define WOLFSSL_DTLS13
40+
#define WOLFSSL_TLS13
41+
#define HAVE_TLS_EXTENSIONS
42+
#define WOLFSSL_SEND_HRR_COOKIE
43+
44+
/* Remove old TLS versions */
45+
#define NO_OLD_TLS
46+
47+
/** Crypto Algorithm Options */
48+
49+
/* ECC for ECDHE key exchange and ECDSA authentication */
50+
#define HAVE_ECC
51+
#define HAVE_SUPPORTED_CURVES
52+
53+
/* AES-GCM for symmetric encryption */
54+
#define HAVE_AESGCM
55+
56+
/* HKDF for key derivation */
57+
#define HAVE_HKDF
58+
59+
/* Timing resistance / side-channel attack protection */
60+
#define TFM_TIMING_RESISTANT
61+
#define ECC_TIMING_RESISTANT
62+
#define WC_RSA_BLINDING
63+
64+
/* Use wolfSSL's internal string comparison instead of system strcasecmp */
65+
#define USE_WOLF_STRCASECMP
66+
67+
/* Remove unneeded features */
68+
#define NO_MAIN_DRIVER
69+
#define NO_DO178
70+
#define NO_RSA
71+
#define NO_DH
72+
73+
#endif /* USER_SETTINGS_H_ */

0 commit comments

Comments
 (0)