# wolfhsm-sys
Raw Rust FFI bindings to [wolfHSM](https://github.com/wolfSSL/wolfHSM),
auto-generated by `bindgen` at build time. All functions are `unsafe`.
Most users should depend on the higher-level [`wolfhsm`](../wolfhsm)
crate instead. Use `wolfhsm-sys` directly only if you need a wolfHSM C
API symbol that is not yet wrapped by `wolfhsm`.
## Why
`wolfhsm-sys` separates the generated FFI from the safe wrapper so that:
- The bindgen output can be regenerated (by bumping
[`wolfhsm-src`](../wolfhsm-src)) without forcing a breaking-change
version bump on [`wolfhsm`](../wolfhsm).
- Downstream crates with unusual requirements can use the raw bindings
without pulling in the opinionated safe API.
- The `links = "wolfhsm"` key prevents multiple copies of the wolfHSM
static archive from being linked into the same binary.
## Usage
```toml
[dependencies]
wolfhsm-sys = "0.1"
```
The crate exposes both the bindgen-generated bindings (the full
`wh_Client_*`, `wh_Comm_*`, `posixTransport*` API) and a small set of
hand-written C shims (`wolfhsm_*`) that stack-allocate the wolfCrypt
key/context structures on the C side — necessary because those types
are opaque from Rust and cannot be zero-initialised here. Any operation
on a key uses the shim; any operation that does not need a wolfCrypt
context uses the bindgen binding directly.
Minimal example: SHA-256 via an already-connected wolfHSM client. The
server connection itself is application-specific (TCP, UDS, or shared
memory transport); see the [`wolfhsm`](../wolfhsm) crate for an
idiomatic safe wrapper.
```rust
use wolfhsm_sys::{whClientContext, wolfhsm_sha256};
/// SAFETY: `client` must be a valid, initialised `whClientContext`
/// (see `wh_Client_Init`). The shim returns 0 on success.
unsafe fn hsm_sha256(
client: *mut whClientContext,
data: &[u8],
) -> Result<[u8; 32], core::ffi::c_int> {
let mut digest = [0u8; 32];
let rc = wolfhsm_sha256(
client,
data.as_ptr(),
data.len() as u32,
digest.as_mut_ptr(),
);
if rc == 0 { Ok(digest) } else { Err(rc) }
}
```
### Build prerequisites
- The [`wolfhsm-src`](../wolfhsm-src) crate must be a direct
`[dependency]` (not `[build-dependency]`) so Cargo propagates its
`DEP_WOLFHSM_SRC_*` metadata to this crate's build script.
`wolfhsm-sys` already declares this dependency; you do not add it
yourself.
- wolfHSM source: set `WOLFHSM_SRC` or initialise the bundled
submodule.
- wolfSSL headers: set `WOLFSSL_DIR` or `WOLFSSL_INCLUDE_DIR`.
See [`wolfhsm-src`](../wolfhsm-src) for full configuration details.
## How it works
`build.rs` performs five steps:
1. **Read wolfSSL metadata** — reads `DEP_WOLFCRYPT_SYS_*` from
`wolfcrypt-sys` (wolfSSL include paths, vendored flag, lib dirs).
2. **Read wolfHSM metadata** — reads `DEP_WOLFHSM_SRC_INCLUDE` and
`DEP_WOLFHSM_SRC_LIB` from `wolfhsm-src` (wolfHSM include path and
compiled library location).
3. **Compile `shims.c`** — a small C translation unit that
stack-allocates wolfCrypt key and context structures and exposes
them via thin wrapper functions callable from Rust.
4. **Emit link directives** — instructs `rustc` to search for
`libwolfhsm.a` in the `wolfhsm-src` output directory and link it,
followed by the wolfSSL library.
5. **Run bindgen** — generates `bindings.rs` in `OUT_DIR` from
`wrapper.h`, which includes `wh_client.h` and the POSIX transport
headers. The allowlist captures `wh_Client_*` functions, `wh_Comm_*`,
`posixTransport*` types and functions, and `WH_*` / `WOLFHSM_*`
constants; wolfSSL internals are excluded.
The bindings cover:
- **Client API** — the complete `wh_Client_*` function set:
connect/disconnect, key generation and caching, ECC/RSA/AES/CMAC/HKDF
operations, NVM object store, counters, certificate management,
authentication, SHE key management, and custom callbacks.
- **Communication layer** — `wh_Comm_*` connection and framing primitives.
- **POSIX transport types** — `PosixTransportTcp*`, `PosixTransportUds*`,
`PosixTransportShm*` structs and init/connect/disconnect functions.
- **Constants and error codes** — `WH_*` and `WOLFHSM_*` result codes
and configuration constants.
- **wolfCrypt-context shims** — `wolfhsm_ecc_*`, `wolfhsm_ed25519_*`,
`wolfhsm_curve25519_*`, `wolfhsm_rsa_*`, `wolfhsm_mldsa_*`,
`wolfhsm_aes_gcm_*`, `wolfhsm_sha{256,384,512}`, `wolfhsm_cmac` for
operations that need a wolfCrypt key/context allocated on the C side.
| `she` | SHE (Secure Hardware Extension) — propagates to `wolfhsm-src` |
## References
- [wolfhsm](../wolfhsm) — safe Rust API; use this unless you have a
specific reason not to
- [wolfhsm-src](../wolfhsm-src) — vendored wolfHSM source build
- [wolfHSM repository](https://github.com/wolfSSL/wolfHSM)
- [wolfHSM documentation](https://www.wolfssl.com/documentation/manuals/wolfhsm/)
- [workspace README](../README.md)
## Copyright
Copyright (C) 2006-2026 wolfSSL Inc.
wolfHSM is copyright wolfSSL Inc. and its contributors.
## License
GPL-3.0-only OR LicenseRef-wolfSSL-commercial.
The underlying wolfHSM C library is licensed under GPL-3.0-or-later with a
commercial option available from [wolfSSL Inc.](https://www.wolfssl.com/license/)