From 024e224dcd90555ec93be9b581b557456831a9cc Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Tue, 20 Oct 2026 15:07:33 -0400 Subject: [PATCH 1/5] Rust wrapper: finalize CHANGELOG for v3.0.0 --- wrapper/rust/wolfssl-wolfcrypt/CHANGELOG.md | 48 +++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/wrapper/rust/wolfssl-wolfcrypt/CHANGELOG.md b/wrapper/rust/wolfssl-wolfcrypt/CHANGELOG.md index 830fc24b310..9158793e76f 100644 --- a/wrapper/rust/wolfssl-wolfcrypt/CHANGELOG.md +++ b/wrapper/rust/wolfssl-wolfcrypt/CHANGELOG.md @@ -37,6 +37,17 @@ Breaking changes: where the exported key ended - ChaCha20Poly1305::finalize() now fails with BAD_FUNC_ARG on a decryption instance; use finalize_verify() to authenticate decrypted data +- Ed25519 signing and verification methods taking a variant and context now + return BAD_FUNC_ARG when a non-empty context is passed with the pure + Ed25519::ED25519 variant, which does not bind a context and previously + silently ignored it. Ed25519 and Ed448 also reject unknown variant values +- The crate build now fails instead of falling back to another wolfSSL when + WOLFSSL_PREFIX is set but does not point at a usable installation, or when + the containing wolfSSL repository is configured (wolfssl/options.h exists) + but the library has not been built there. Previously the build could + silently link against a system library built with different options +- The crate build now fails if wolfSSL was built with asynchronous crypto + support (WOLFSSL_ASYNC_CRYPT), which the wrapper does not support New features: @@ -50,6 +61,12 @@ New features: key and so implement Keypair::verifying_key() without it being able to fail - Add Lms::export_pub_ex() to set the heap hint and device ID of the exported verify only key +- The crate now declares `links = "wolfssl"` and publishes the directory of a + shared wolfSSL library as the LIBDIRS metadata, so dependent crates' build + scripts can read it from DEP_WOLFSSL_LIBDIRS (e.g. to set an rpath) +- build.rs looks for the library under either lib or lib64 in WOLFSSL_PREFIX, + recognizes MinGW, Cygwin and MSVC library file names, and reruns when + WOLFSSL_PREFIX changes Fixes and improvements: @@ -87,6 +104,37 @@ Fixes and improvements: - RNG::generate_block() (and the rand_core implementation built on it) now fills buffers larger than RNG_MAX_BLOCK_LEN by splitting them into multiple DRBG requests, instead of failing with BAD_FUNC_ARG +- RustCrypto digest and MAC update implementations (SHA, BLAKE2, HMAC, CMAC) + now split inputs larger than 4GB into multiple wolfCrypt updates instead of + panicking +- AES CTR and OFB StreamCipher implementations no longer panic on buffers of + 4GB or more, and no longer create aliasing shared and mutable references to + in-place buffers +- rsa_pkcs1v15::SigningKey validates its public components at construction, + so Keypair::verifying_key() can no longer panic; rsa_pkcs1v15::VerifyingKey + is now usable in builds without RNG support +- Fix memory leak when re-initializing SHA, SHA-2, SHA-3 and SHAKE instances +- Fix a possible dangling WC_RNG pointer held by a Curve25519Key +- ECC keys are created with wc_ecc_key_new_ex() when available so the heap + hint and device ID are applied at initialization +- kdf::ssh_kdf() rejects hash type values that do not fit in a byte instead + of truncating them +- Zeroize additional sensitive temporaries: ML-KEM private keys and shared + secrets, PBKDF2/scrypt intermediate password hashes, AEAD keys, and the + ChaCha20-Poly1305 context on error paths +- Numerous cfg detection fixes so the crate builds and links against reduced + wolfSSL configurations, including: separate SHA3-224/256/384/512 detection; + AES-CFB/OFB decrypt; verify-only ECC (ecdsa module) and ECC export; + RSA without RNG, private key or signing support; Ed25519/Ed448 without RNG + or key generation; Curve25519 import, export and shared secret; ML-KEM per + operation and parameter set, and builds with WC_NO_CONSTRUCTORS; ML-DSA + public/private import and export; LMS without key generation; PBKDF2 + password hashing with only some of SHA-256/384/512 enabled; and the rsa_oaep + probe under FIPS +- Numerous documentation corrections, including output buffer sizes for HKDF, + KDF and BLAKE2, AES-XTS key sizes, Ed448 prehash (SHAKE256), and documenting + wolfcrypt_cleanup() preconditions and RNG::health_test_ex() seed_b + requirements ## v2.2.0 From 7b4924593649eddd27ec04b2649a0aaaa3668448 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Tue, 20 Oct 2026 15:09:43 -0400 Subject: [PATCH 2/5] Rust wrapper: squelch a couple compiler warnings to collapse if statements --- wrapper/rust/wolfssl-wolfcrypt/src/ed25519.rs | 6 ++---- wrapper/rust/wolfssl-wolfcrypt/src/ed448.rs | 6 ++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/wrapper/rust/wolfssl-wolfcrypt/src/ed25519.rs b/wrapper/rust/wolfssl-wolfcrypt/src/ed25519.rs index cf26bce3134..10fe729ee53 100644 --- a/wrapper/rust/wolfssl-wolfcrypt/src/ed25519.rs +++ b/wrapper/rust/wolfssl-wolfcrypt/src/ed25519.rs @@ -1427,10 +1427,8 @@ impl Ed25519 { let signature_size = crate::buffer_len_to_u32(signature.len())?; // For the prehash variant, the input must have been exactly one // prehash. The streaming state is consumed either way. - if let Some(len) = self.ph_stream_len { - if len != Self::PREHASH_SIZE { - return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); - } + if let Some(len) = self.ph_stream_len && len != Self::PREHASH_SIZE { + return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); } self.ph_stream_len = None; let mut res = 0i32; diff --git a/wrapper/rust/wolfssl-wolfcrypt/src/ed448.rs b/wrapper/rust/wolfssl-wolfcrypt/src/ed448.rs index 91145bae776..3d09c7a1c96 100644 --- a/wrapper/rust/wolfssl-wolfcrypt/src/ed448.rs +++ b/wrapper/rust/wolfssl-wolfcrypt/src/ed448.rs @@ -1335,10 +1335,8 @@ impl Ed448 { let signature_size = crate::buffer_len_to_u32(signature.len())?; // For the prehash variant, the input must have been exactly one // prehash. The streaming state is consumed either way. - if let Some(len) = self.ph_stream_len { - if len != Self::PREHASH_SIZE { - return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); - } + if let Some(len) = self.ph_stream_len && len != Self::PREHASH_SIZE { + return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); } self.ph_stream_len = None; let mut res = 0i32; From 5e17e884a19d4b12d1b87520b960bf393ad2aa5c Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Tue, 20 Oct 2026 15:16:40 -0400 Subject: [PATCH 3/5] Rust wrapper: bump wolfssl-wolfcrypt crate to v3.0.0 --- wrapper/rust/wolfssl-wolfcrypt/Cargo.lock | 2 +- wrapper/rust/wolfssl-wolfcrypt/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/wrapper/rust/wolfssl-wolfcrypt/Cargo.lock b/wrapper/rust/wolfssl-wolfcrypt/Cargo.lock index 434ce46c606..62e5e84ab0a 100644 --- a/wrapper/rust/wolfssl-wolfcrypt/Cargo.lock +++ b/wrapper/rust/wolfssl-wolfcrypt/Cargo.lock @@ -426,7 +426,7 @@ checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] name = "wolfssl-wolfcrypt" -version = "2.2.0" +version = "3.0.0" dependencies = [ "aead", "bindgen", diff --git a/wrapper/rust/wolfssl-wolfcrypt/Cargo.toml b/wrapper/rust/wolfssl-wolfcrypt/Cargo.toml index ef0e274bd59..be1a2804c73 100644 --- a/wrapper/rust/wolfssl-wolfcrypt/Cargo.toml +++ b/wrapper/rust/wolfssl-wolfcrypt/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wolfssl-wolfcrypt" -version = "2.2.0" +version = "3.0.0" edition = "2024" description = "Rust wrapper for wolfssl C library cryptographic functionality" license = "GPL-3.0" From 874448f1ce492ce51dd5bc836f332b9c15620afc Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Tue, 3 Nov 2026 12:02:58 -0500 Subject: [PATCH 4/5] fixup changelog --- wrapper/rust/wolfssl-wolfcrypt/CHANGELOG.md | 26 ++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/wrapper/rust/wolfssl-wolfcrypt/CHANGELOG.md b/wrapper/rust/wolfssl-wolfcrypt/CHANGELOG.md index 9158793e76f..58e7493c9d9 100644 --- a/wrapper/rust/wolfssl-wolfcrypt/CHANGELOG.md +++ b/wrapper/rust/wolfssl-wolfcrypt/CHANGELOG.md @@ -51,12 +51,24 @@ Breaking changes: New features: +- Support building against the wolfSSL FIPS v5.2.3 module. On that module + the HKDF and RNG constructors fall back to the older wolfCrypt functions + and refuse a heap hint or device ID, RSA::set_rng() does not bind the RNG + for blinding (the module is built without RSA blinding), RNG::reseed() is + not available, and RSA::pss_verify_check() is available +- Add fips::PrivateKeyRead, a guard that enables FIPS private key reads on + the current thread until it is dropped; guards can be nested +- Add fips::run_all_self_tests() to run all FIPS self tests (CASTs) once, so + concurrent first use of an algorithm cannot fail while its self test is + running - Add the rand_core_0_9 feature: RNG implements the rand_core 0.9 TryRngCore and TryCryptoRng traits, alongside the rand_core 0.10 ones, for users of the rand 0.9 ecosystem - Add Curve25519Key::generate_shared_rng() to generate a key from an RNG shared between keys via Rc (requires the alloc feature) -- Add HMAC::copy(), a fallible equivalent of HMAC::clone() +- Add HMAC::copy(), a fallible equivalent of HMAC::clone(). HMAC::copy(), + the Clone implementation for HMAC and the hmac_mac types are only available + when the wolfSSL library provides wc_HmacCopy() - Add ed25519::SigningKey and ed448::SigningKey, which always carry a public key and so implement Keypair::verifying_key() without it being able to fail - Add Lms::export_pub_ex() to set the heap hint and device ID of the exported @@ -64,6 +76,12 @@ New features: - The crate now declares `links = "wolfssl"` and publishes the directory of a shared wolfSSL library as the LIBDIRS metadata, so dependent crates' build scripts can read it from DEP_WOLFSSL_LIBDIRS (e.g. to set an rpath) +- Add Ed25519::PREHASH_SIZE and Ed448::PREHASH_SIZE, the required input size + for prehash signing and verification +- Publish build metadata to dependent crates' build scripts: the directory of + a shared wolfSSL library as DEP_WOLFSSL_LIBDIRS (e.g. to set an rpath), and + DEP_WOLFSSL_FIPS and DEP_WOLFSSL_FIPS_V5_2_3 when wolfSSL is a FIPS build or + specifically the FIPS v5.2.3 module - build.rs looks for the library under either lib or lib64 in WOLFSSL_PREFIX, recognizes MinGW, Cygwin and MSVC library file names, and reruns when WOLFSSL_PREFIX changes @@ -73,6 +91,12 @@ Fixes and improvements: - Fix undefined behavior in HMAC::clone(): wc_HmacCopy() takes its source by non-const pointer and may write through it, but the pointer was cast from a shared reference. The wolfSSL context is now held in an UnsafeCell +- AES-GCM encryption with a caller-supplied IV (GCM::encrypt() and the + Aes128Gcm/Aes192Gcm/Aes256Gcm AEAD types) now works in FIPS builds, which do + not export wc_AesGcmEncrypt(); the same operation is done with FIPS + approved calls instead +- rsa_oaep::DecryptingKey::generate() and rsa_pkcs1v15::SigningKey::generate() + return BAD_FUNC_ARG instead of overflowing on extremely large key sizes - Fix a panic in Keypair::verifying_key() for Ed25519 and Ed448 keys with no public key, such as after new() or import_private_only() - Validate PBKDF2 and scrypt password hash output length against the PHC From d0b1c46726d29998d92c35967781ca5b6ddccd89 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Tue, 3 Nov 2026 12:04:47 -0500 Subject: [PATCH 5/5] Rust wrapper: update README for version 3.0.0 --- wrapper/rust/wolfssl-wolfcrypt/README.md | 52 +++++++++++++++++++++--- 1 file changed, 47 insertions(+), 5 deletions(-) diff --git a/wrapper/rust/wolfssl-wolfcrypt/README.md b/wrapper/rust/wolfssl-wolfcrypt/README.md index 62d56875458..78dc175f92a 100644 --- a/wrapper/rust/wolfssl-wolfcrypt/README.md +++ b/wrapper/rust/wolfssl-wolfcrypt/README.md @@ -3,7 +3,8 @@ The `wolfssl-wolfcrypt` crate is a Rust wrapper for the wolfCrypt cryptographic algorithms portion of the wolfSSL C library. -This crate requires wolfSSL version 5.9.0 or newer. +This crate requires wolfSSL version 5.9.0 or newer, or the wolfSSL FIPS +v5.2.3 module or newer. The crate uses `no_std` so that no Rust standard library is required. This makes it well-suited for embedded/bare-metal environments. @@ -22,9 +23,12 @@ For example: ``` [dependencies] -wolfssl-wolfcrypt = "2.0" +wolfssl-wolfcrypt = "3.0" ``` +When upgrading from an earlier major version, see the "Breaking changes" +sections of [CHANGELOG.md](CHANGELOG.md). + ## API Coverage This crate provides a wrapper API for the following wolfCrypt C library @@ -70,9 +74,9 @@ default. | --------------- | ---------------- | ------------------------------------- | | `digest` | `digest` | SHA (sha_digest), BLAKE2 (blake2_digest) | | `mac` | `digest` (mac) | HMAC (hmac_mac), CMAC (cmac_mac), BLAKE2 (blake2_mac) | -| `signature` | `signature` | ECDSA (ecdsa), RSA PKCS#1 v1.5 (rsa_pkcs1v15) | +| `signature` | `signature` | ECDSA (ecdsa), RSA PKCS#1 v1.5 (rsa_pkcs1v15), Ed25519 (ed25519), Ed448 (ed448) | | `cipher` | `cipher` | AES (aes) | -| `aead` | `aead` | AES-GCM/CCM/EAX (aes), ChaCha20-Poly1305 | +| `aead` | `aead` | AES-GCM/CCM (aes), ChaCha20-Poly1305/XChaCha20-Poly1305 (chacha20_poly1305) | | `rand_core` | `rand_core` | RNG (random) | | `rand_core_0_9` | `rand_core` 0.9 | RNG (random) | | `kem` | `kem` | ML-KEM (mlkem_kem) | @@ -106,9 +110,23 @@ Enable features in your `Cargo.toml`, for example: ``` [dependencies] -wolfssl-wolfcrypt = { version = "2.0", features = ["digest", "signature"] } +wolfssl-wolfcrypt = { version = "3.0", features = ["digest", "signature"] } ``` +## FIPS + +When the crate is built against a wolfSSL FIPS module, the `fips` module +provides FIPS-specific APIs: + + * `fips::run_all_self_tests()` runs all FIPS self tests (CASTs) once. + Calling it at startup ensures that concurrent first use of an algorithm + cannot fail while that algorithm's self test is running. + * `fips::PrivateKeyRead::enable()` returns a guard that allows private key + data to be read on the current thread until the guard is dropped. + Guards can be nested. + * `fips::set_private_key_read_enable()` enables or disables private key + reads directly. + ## Build Notes ### WOLFSSL_PREFIX @@ -123,6 +141,30 @@ For example: WOLFSSL_PREFIX=/opt/my-wolfssl-build cargo build ``` +The library may be under either `lib` or `lib64` in the prefix. If +`WOLFSSL_PREFIX` is set but does not point at a usable wolfSSL installation, +the build fails rather than falling back to another wolfSSL library. + +When `WOLFSSL_PREFIX` is unset and the crate is built from within a wolfSSL +source repository that has been configured, it builds against the library in +that repository, and the build fails if that library has not been built yet. + +### Unsupported wolfSSL Configurations + +The crate build fails if the wolfSSL library was built with asynchronous +crypto support (`WOLFSSL_ASYNC_CRYPT`), which the wrapper does not support. + +### Metadata for Dependent Crates + +The crate declares `links = "wolfssl"` and publishes the following values to +the build scripts of crates that depend on it directly: + +| Variable | Value | +| ------------------------- | ----- | +| `DEP_WOLFSSL_LIBDIRS` | Directory containing a shared wolfSSL library (e.g. to set an rpath) | +| `DEP_WOLFSSL_FIPS` | `1` when wolfSSL is a FIPS build | +| `DEP_WOLFSSL_FIPS_V5_2_3` | `1` when wolfSSL is the FIPS v5.2.3 module | + ### Cross-Compiling Ensure that the target you want to build for is installed for Rust.