Skip to content

Commit ff51620

Browse files
MarkAtwoodclaude
andcommitted
feat: add riscv-bare-metal feature for Caliptra firmware targets
Adds support for building wolfCrypt targeting riscv32imc-unknown-none-elf (Caliptra firmware). New files in wolfssl-src: user_settings_riscv.h — minimal wolfSSL config: single-threaded, no filesystem, custom RNG seeded from caliptra_generate_seed(), STRING_USER with __builtin_mem* instead of libc riscv_bare_metal_helpers.c — bare-metal strncat/strnstr/strcasecmp implemented with __builtin_memcpy/memcmp only, no libc The riscv-bare-metal feature is wired through the full dependency chain: wolfssl-src → wolfcrypt-sys → wolfcrypt-rs → wolfcrypt → wolfcrypt-dpe. wolfssl-src selects user_settings_riscv.h over user_settings.h when the feature is active, copies it to OUT_DIR as user_settings.h so it shadows the default, and compiles only ssl.c (which includes the remaining translation units as a unity build on this target). wolfcrypt-sys/build.rs threads the RISC-V settings dir into bindgen and drops the ../../wolfssl adjacent-repo fallback that was only useful in a specific local checkout layout. wolfcrypt-rs now parses LIBWOLFSSL_VERSION_STRING from wolfssl/version.h at build time and exposes it as pub const WOLFSSL_VERSION: &str for runtime diagnostics. wolfcrypt-dpe is now unconditionally #![no_std] (the std feature gate was the only thing keeping it conditional) and bumps caliptra-dpe to fw-2.1.0 (rev cfc9a713), which renamed its workspace packages from caliptra-dpe-crypto/caliptra-dpe/caliptra-dpe-platform to crypto/dpe/platform. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent a2bb1fa commit ff51620

13 files changed

Lines changed: 508 additions & 65 deletions

File tree

wolfcrypt-dpe-conformance/Cargo.toml

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
11
[package]
22
name = "wolfcrypt-dpe-conformance"
3+
authors = ["WolfSSL Inc"]
34
version = "0.1.0"
45
edition = "2021"
56
license = "MIT"
6-
publish = false
77
description = "Cross-validation and conformance tests for wolfcrypt-dpe against caliptra-dpe reference"
8-
keywords = ["wolfcrypt", "wolfssl", "fips"]
8+
homepage = "http://wolfssl.com"
9+
repository = "https://github.com/wolfSSL/wolfssl-rs"
10+
keywords = ["wolfcrypt", "wolfssl", "fips", "caliptra", "dpe"]
11+
categories = ["cryptography"]
912

1013
[lib]
1114
path = "src/lib.rs"
1215

1316
[dev-dependencies]
1417
# === Wolf backend ===
15-
wolfcrypt-dpe = { path = "../wolfcrypt-dpe" }
16-
wolfcrypt-ring-compat = { path = "../wolfcrypt-ring-compat", default-features = false, features = ["wolfcrypt-rs", "alloc"] }
18+
wolfcrypt-dpe = { version = "0.1.0", path = "../wolfcrypt-dpe" }
19+
wolfcrypt-ring-compat = { version = "1.0", path = "../wolfcrypt-ring-compat", default-features = false, features = ["wolfcrypt-rs", "alloc"] }
1720

1821
# === Reference backend (RustCrypto) — same crypto crate with rustcrypto feature ===
1922
caliptra-dpe-crypto = { git = "https://github.com/chipsalliance/caliptra-dpe", rev = "6dfc502a30d443e5e054db1344a97eeb823ea5b9", package = "caliptra-dpe-crypto", default-features = false, features = ["rustcrypto"] }

wolfcrypt-dpe/Cargo.toml

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,43 @@
11
[package]
22
name = "wolfcrypt-dpe"
3+
authors = ["WolfSSL Inc"]
34
version = "0.1.0"
45
edition = "2021"
56
license = "MIT"
6-
keywords = ["wolfcrypt", "wolfssl", "fips"]
7+
description = "Caliptra DPE Crypto trait implementation backed by wolfCrypt"
8+
homepage = "http://wolfssl.com"
9+
repository = "https://github.com/wolfSSL/wolfssl-rs"
10+
keywords = ["wolfcrypt", "wolfssl", "fips", "caliptra", "dpe"]
11+
categories = ["cryptography"]
712

813
[lib]
914
name = "wolfcrypt_dpe"
1015

11-
# For no_std targets (e.g. Caliptra), depend with:
12-
# wolfcrypt-dpe = { ..., default-features = false }
1316
[features]
14-
default = ["std"]
15-
std = ["wolfcrypt/digest", "wolfcrypt/rand"]
17+
riscv-bare-metal = ["wolfcrypt/riscv-bare-metal"]
1618

1719
[dependencies]
1820
# wolfcrypt from the local workspace -- the ONLY crypto dependency
19-
wolfcrypt = { path = "../wolfcrypt", default-features = false, features = [
21+
wolfcrypt = { version = "0.1.0", path = "../wolfcrypt", default-features = false, features = [
2022
"digest", "hkdf", "ecdsa", "rand",
2123
] }
2224

2325
# RustCrypto traits used in the public/internal API
24-
digest_trait = { package = "digest", version = "0.10" }
25-
signature_trait = { package = "signature", version = "2.2" }
26-
rand_core = "0.10"
26+
digest_trait = { package = "digest", version = "0.10", default-features = false }
27+
signature_trait = { package = "signature", version = "2.2", default-features = false }
28+
rand_core = { version = "0.10", default-features = false }
2729

2830
# Constant-time comparison
29-
subtle = "2"
30-
zeroize = "1"
31+
subtle = { version = "2", default-features = false }
32+
zeroize = { version = "1", default-features = false }
3133

32-
# caliptra-dpe crypto trait -- pinned to exact commit
33-
caliptra-dpe-crypto = { git = "https://github.com/chipsalliance/caliptra-dpe", rev = "6dfc502a30d443e5e054db1344a97eeb823ea5b9", package = "caliptra-dpe-crypto", default-features = false }
34+
# caliptra-dpe crypto trait -- pinned to exact commit (fw-2.1.0)
35+
caliptra-dpe-crypto = { git = "https://github.com/chipsalliance/caliptra-dpe", rev = "cfc9a713882ca562a0ae6565198129e6da121a42", package = "crypto", default-features = false }
3436

3537
[dev-dependencies]
3638
hex = "0.4"
3739

3840
# DPE engine + platform for integration tests (same pinned commit as crypto trait)
39-
caliptra-dpe = { git = "https://github.com/chipsalliance/caliptra-dpe", rev = "6dfc502a30d443e5e054db1344a97eeb823ea5b9", package = "caliptra-dpe", default-features = false, features = ["p384"] }
40-
caliptra-dpe-platform = { git = "https://github.com/chipsalliance/caliptra-dpe", rev = "6dfc502a30d443e5e054db1344a97eeb823ea5b9", package = "caliptra-dpe-platform", default-features = false, features = ["rustcrypto"] }
41+
caliptra-dpe = { git = "https://github.com/chipsalliance/caliptra-dpe", rev = "cfc9a713882ca562a0ae6565198129e6da121a42", package = "dpe", default-features = false, features = ["p384"] }
42+
caliptra-dpe-platform = { git = "https://github.com/chipsalliance/caliptra-dpe", rev = "cfc9a713882ca562a0ae6565198129e6da121a42", package = "platform", default-features = false, features = ["rustcrypto"] }
4143
caliptra-cfi-lib = { git = "https://github.com/chipsalliance/caliptra-cfi.git", package = "caliptra-cfi-lib", rev = "767d4ef59a106aea683b883c07bd65456fb3ba6b", default-features = false, features = ["cfi-test"] }

wolfcrypt-dpe/src/lib.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,9 @@
33
//! This crate does NOT contain any FFI code. All cryptographic operations
44
//! are performed through the safe Rust API of the `wolfcrypt` crate.
55
6-
#![cfg_attr(not(feature = "std"), no_std)]
6+
#![no_std]
77

88
extern crate alloc;
9-
/// Prelude for no_std compatibility.
10-
///
11-
/// When `std` is disabled, re-exports core alloc types so that consumer
12-
/// modules can `use crate::prelude::*` without caring about the feature.
139
pub(crate) mod prelude {
1410
pub use alloc::vec;
1511
pub use alloc::vec::Vec;

wolfcrypt-rs/Cargo.toml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@
22
name = "wolfcrypt-rs"
33
description = "Low-level FFI bindings for wolfSSL/wolfCrypt cryptographic library."
44
version = "0.1.0"
5-
authors = ["wolfSSL"]
5+
authors = ["WolfSSL Inc"]
66
edition = "2021"
77
license = "MIT"
8-
keywords = ["wolfcrypt", "wolfssl", "fips"]
8+
homepage = "http://wolfssl.com"
9+
repository = "https://github.com/wolfSSL/wolfssl-rs"
10+
keywords = ["wolfcrypt", "wolfssl", "fips", "cryptography"]
11+
categories = ["cryptography"]
912
rust-version = "1.71.0"
1013
build = "build.rs"
1114
links = "wolfssl"
@@ -16,6 +19,7 @@ wolfcrypt-sys = { version = "0.1.0", path = "../wolfcrypt-sys", default-features
1619
[features]
1720
default = []
1821
fips = ["wolfcrypt-sys/fips"]
22+
riscv-bare-metal = ["wolfcrypt-sys/riscv-bare-metal"]
1923

2024
[build-dependencies]
2125
cc = { workspace = true, features = ["parallel"] }

wolfcrypt-rs/build.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,21 @@ fn main() {
4343

4444
let mut shim_build = cc::Build::new();
4545
shim_build.include(&wolfssl_include);
46+
// For riscv-bare-metal, put OUT_DIR first so the RISC-V user_settings.h
47+
// shadows the default one, and add bare-metal stub headers.
48+
if cfg!(feature = "riscv-bare-metal") {
49+
let out_dir = env::var("OUT_DIR").unwrap();
50+
shim_build.include(&out_dir);
51+
if let Ok(stubs) = env::var("WOLFSSL_BARE_METAL_STUBS") {
52+
shim_build.include(&stubs);
53+
}
54+
// Copy RISC-V settings to our OUT_DIR too
55+
let src_settings = std::path::Path::new(&settings_include).join("user_settings_riscv.h");
56+
let dst = std::path::Path::new(&out_dir).join("user_settings.h");
57+
if src_settings.exists() && !dst.exists() {
58+
std::fs::copy(&src_settings, &dst).ok();
59+
}
60+
}
4661
shim_build.include(&settings_include);
4762
if vendored {
4863
shim_build.define("WOLFSSL_USER_SETTINGS", None);
@@ -75,6 +90,9 @@ fn main() {
7590
.unwrap_or_else(|_| panic!("DEP_WOLFCRYPT_SYS_LIBCRYPTO not set — is wolfcrypt-sys a dependency?")));
7691
println!("cargo:VENDORED={}", env::var("DEP_WOLFCRYPT_SYS_VENDORED")
7792
.unwrap_or_else(|_| panic!("DEP_WOLFCRYPT_SYS_VENDORED not set — is wolfcrypt-sys a dependency?")));
93+
let version = env::var("DEP_WOLFCRYPT_SYS_VERSION").unwrap_or_else(|_| "unknown".to_string());
94+
println!("cargo:VERSION={version}");
95+
println!("cargo:rustc-env=WOLFSSL_VERSION={version}");
7896

7997
// --- rerun-if-changed ---
8098
println!("cargo:rerun-if-changed=build.rs");

wolfcrypt-rs/src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ pub const CHACHA_ALLOC_SIZE: usize = 128;
4848
#[cfg(wolfssl_chacha20_poly1305)]
4949
pub const CHACHA_POLY_AEAD_ALLOC_SIZE: usize = 192;
5050

51+
/// Version string of the linked wolfSSL C library (e.g. `"5.7.4"`).
52+
///
53+
/// Set at compile time from `LIBWOLFSSL_VERSION_STRING` in `wolfssl/version.h`.
54+
/// Returns `"unknown"` if the header was not found during the build.
55+
pub const WOLFSSL_VERSION: &str = env!("WOLFSSL_VERSION");
56+
5157
// ================================================================
5258
// Opaque types (used behind pointers)
5359
// ================================================================

wolfcrypt-sys/Cargo.toml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,21 @@
11
[package]
22
name = "wolfcrypt-sys"
3+
authors = ["WolfSSL Inc"]
34
version = "0.1.0"
45
edition = "2021"
56
description = "Auto-generated Rust FFI bindings to wolfSSL via bindgen"
67
license = "MIT"
7-
keywords = ["wolfcrypt", "wolfssl", "fips"]
8+
homepage = "http://wolfssl.com"
9+
repository = "https://github.com/wolfSSL/wolfssl-rs"
10+
keywords = ["wolfcrypt", "wolfssl", "fips", "ffi", "cryptography"]
11+
categories = ["cryptography"]
812
links = "wolfcrypt_sys"
913

1014
[features]
1115
default = []
1216
fips = []
1317
vendored = []
18+
riscv-bare-metal = ["wolfssl-src/riscv-bare-metal"]
1419

1520
[build-dependencies]
1621
bindgen = "0.72.0"

wolfcrypt-sys/build.rs

Lines changed: 46 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@
77
// 2. WOLFSSL_DIR → install prefix (lib/ + include/)
88
// 3. `vendored` feature / WOLFSSL_SRC → compile via wolfssl-src
99
// 4. pkg-config → system library
10-
// 5. ../../wolfssl exists → compile via wolfssl-src
11-
// 6. panic with instructions
10+
// 5. panic with instructions
1211

1312
use std::collections::HashSet;
1413
use std::env;
@@ -208,6 +207,12 @@ fn generate_bindings(
208207
builder = builder.clang_arg(format!("-I{}", settings_dir.display()));
209208
}
210209
builder = builder.clang_arg("-DWOLFSSL_USER_SETTINGS");
210+
// For riscv-bare-metal, add stub headers (stdio.h, etc.)
211+
if cfg!(feature = "riscv-bare-metal") {
212+
if let Ok(stubs) = env::var("WOLFSSL_BARE_METAL_STUBS") {
213+
builder = builder.clang_arg(format!("-I{}", stubs));
214+
}
215+
}
211216
} else {
212217
// For system/pkg-config builds, tell settings.h to pull in options.h
213218
// so that all feature flags (TLS 1.3, SNI, etc.) are visible to bindgen.
@@ -269,8 +274,7 @@ fn main() {
269274
// 2. WOLFSSL_DIR → install prefix
270275
// 3. vendored feature / WOLFSSL_SRC → wolfssl-src
271276
// 4. pkg-config → system
272-
// 5. ../../wolfssl fallback → wolfssl-src
273-
// 6. panic
277+
// 5. panic
274278

275279
if let (Ok(lib_dir), Ok(include_dir)) = (
276280
env::var("WOLFSSL_LIB_DIR"),
@@ -295,21 +299,15 @@ fn main() {
295299
} else if let Some((include_dir, lib_dirs, defines)) = try_pkg_config() {
296300
do_system(&include_dir, &lib_dirs, &manifest_dir, &defines, is_fips);
297301
} else {
298-
// Last resort: try vendored build if source exists
299-
let candidate = manifest_dir.join("..").join("..").join("wolfssl");
300-
if candidate.exists() {
301-
do_vendored(&manifest_dir, is_fips);
302-
} else {
303-
panic!(
304-
"wolfSSL not found. Either:\n \
305-
- Install wolfssl and ensure pkg-config can find it\n \
306-
- Set WOLFSSL_DIR to a wolfssl install prefix\n \
307-
- Set WOLFSSL_LIB_DIR and WOLFSSL_INCLUDE_DIR\n \
308-
- Enable the `vendored` feature and set WOLFSSL_SRC\n \
309-
- Clone wolfssl adjacent to this workspace:\n \
310-
git clone https://github.com/wolfSSL/wolfssl.git"
311-
);
312-
}
302+
panic!(
303+
"wolfSSL not found. Either:\n \
304+
- Install wolfssl and ensure pkg-config can find it\n \
305+
- Set WOLFSSL_DIR to a wolfssl install prefix\n \
306+
- Set WOLFSSL_LIB_DIR and WOLFSSL_INCLUDE_DIR\n \
307+
- Enable the `vendored` feature and set WOLFSSL_SRC\n \
308+
- Clone wolfssl: git clone https://github.com/wolfSSL/wolfssl.git\n \
309+
then set WOLFSSL_SRC to the cloned path"
310+
);
313311
}
314312

315313
println!("cargo:rerun-if-changed=build.rs");
@@ -370,12 +368,19 @@ fn do_vendored(manifest_dir: &Path, is_fips: bool) {
370368
let artifacts = builder.build();
371369
let active_cfgs = emit_cfg_flags(&artifacts.defines);
372370

371+
// For riscv-bare-metal, bindgen must see the RISC-V user_settings.h
372+
// (copied to OUT_DIR by wolfssl-src) rather than the default.
373+
let settings_dir = if cfg!(feature = "riscv-bare-metal") {
374+
PathBuf::from(env::var("OUT_DIR").unwrap())
375+
} else {
376+
artifacts.settings_include_dir.clone()
377+
};
373378
generate_bindings(
374379
&artifacts.include_dir,
375380
manifest_dir,
376381
is_fips,
377382
true,
378-
Some(&artifacts.settings_include_dir),
383+
Some(&settings_dir),
379384
);
380385

381386
emit_metadata(
@@ -412,6 +417,25 @@ fn do_system(
412417
emit_metadata(&active_cfgs, include_dir, include_dir, "", lib_dirs, false);
413418
}
414419

420+
/// Parse `LIBWOLFSSL_VERSION_STRING` from `<include_dir>/wolfssl/version.h`.
421+
fn parse_wolfssl_version(include_dir: &Path) -> String {
422+
let version_h = include_dir.join("wolfssl").join("version.h");
423+
let content = match std::fs::read_to_string(&version_h) {
424+
Ok(s) => s,
425+
Err(_) => return "unknown".to_string(),
426+
};
427+
for line in content.lines() {
428+
let trimmed = line.trim();
429+
if let Some(rest) = trimmed.strip_prefix("#define LIBWOLFSSL_VERSION_STRING") {
430+
let rest = rest.trim();
431+
if let Some(ver) = rest.strip_prefix('"').and_then(|s| s.strip_suffix('"')) {
432+
return ver.to_string();
433+
}
434+
}
435+
}
436+
"unknown".to_string()
437+
}
438+
415439
/// Emit cargo metadata for downstream crates.
416440
fn emit_metadata(
417441
active_cfgs: &[String],
@@ -421,6 +445,8 @@ fn emit_metadata(
421445
lib_dirs: &[PathBuf],
422446
vendored: bool,
423447
) {
448+
let version = parse_wolfssl_version(include_dir);
449+
println!("cargo:VERSION={version}");
424450
println!("cargo:CFGS={}", active_cfgs.join(","));
425451
println!("cargo:ALL_CFGS={}", ALL_WOLFSSL_CFGS.join(","));
426452
println!("cargo:INCLUDE={}", include_dir.display());

wolfcrypt/Cargo.toml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,16 @@
44

55
[package]
66
name = "wolfcrypt"
7+
authors = ["WolfSSL Inc"]
78
version = "0.1.0"
89
edition = "2021"
910
rust-version = "1.71.0"
1011
license = "MIT"
11-
keywords = ["wolfcrypt", "wolfssl", "fips"]
12+
description = "RustCrypto trait implementations backed by wolfCrypt"
13+
homepage = "http://wolfssl.com"
14+
repository = "https://github.com/wolfSSL/wolfssl-rs"
15+
keywords = ["wolfcrypt", "wolfssl", "fips", "rustcrypto", "cryptography"]
16+
categories = ["cryptography"]
1217

1318
[features]
1419
default = ["digest", "rand"]
@@ -41,9 +46,10 @@ rsa-direct = ["rsa", "rand"]
4146
cryptocb = []
4247
hpke = ["rand"]
4348
fips = ["wolfcrypt-rs/fips"]
49+
riscv-bare-metal = ["wolfcrypt-rs/riscv-bare-metal"]
4450

4551
[dependencies]
46-
wolfcrypt-rs = { path = "../wolfcrypt-rs" }
52+
wolfcrypt-rs = { version = "0.1.0", path = "../wolfcrypt-rs" }
4753

4854
# RustCrypto trait crates (renamed to avoid module name collision).
4955
#

wolfssl-src/Cargo.toml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,20 @@
11
[package]
22
name = "wolfssl-src"
3+
authors = ["WolfSSL Inc"]
34
version = "0.1.0"
45
edition = "2021"
56
description = "Compile wolfSSL from source for use by wolfcrypt-sys"
67
license = "MIT"
7-
keywords = ["wolfcrypt", "wolfssl", "fips"]
8+
homepage = "http://wolfssl.com"
9+
repository = "https://github.com/wolfSSL/wolfssl-rs"
10+
keywords = ["wolfcrypt", "wolfssl", "fips", "cryptography"]
11+
categories = ["cryptography"]
12+
13+
[features]
14+
default = []
15+
# Use the minimal bare-metal user_settings_riscv.h instead of the full
16+
# user_settings.h. Intended for riscv32imc-unknown-none-elf targets.
17+
riscv-bare-metal = []
818

919
[dependencies]
1020
cc = { version = "1.2.26", features = ["parallel"] }

0 commit comments

Comments
 (0)