Rust crate updates 2026-05-05#10402
Conversation
There was a problem hiding this comment.
Pull request overview
This PR updates the wolfssl-wolfcrypt Rust wrapper to (1) improve RNG lifetime safety across FFI consumers, (2) add RustCrypto trait integrations for BLAKE2 digest/MAC, and (3) extend AEAD support with AES-192 CCM/GCM wrappers, along with corresponding test updates.
Changes:
- Refactors
RNGto own a C-heapWC_RNG*and updates RNG-taking APIs to accept&RNG(plus newset_shared_rng(Arc<RNG>)for consumers that store an RNG pointer internally). - Adds RustCrypto
digest::Digestwrappers (blake2_digest) anddigest::Macwrappers (blake2_mac) for BLAKE2b/BLAKE2s. - Adds AEAD wrappers and tests for AES-192-GCM and AES-192-CCM, and adds
Clonesupport for HMAC MAC types.
Reviewed changes
Copilot reviewed 28 out of 28 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| wrapper/rust/wolfssl-wolfcrypt/tests/test_rsa.rs | Updates tests to new RNG borrowing/sharing patterns (&RNG, set_shared_rng). |
| wrapper/rust/wolfssl-wolfcrypt/tests/test_random.rs | Updates RNG tests to match RNG methods taking &self (no mut). |
| wrapper/rust/wolfssl-wolfcrypt/tests/test_hmac_mac.rs | Adds a clone/forking test to validate cloned HMAC MAC state equivalence. |
| wrapper/rust/wolfssl-wolfcrypt/tests/test_ecc.rs | Updates ECC tests for RNG ownership and shared RNG binding. |
| wrapper/rust/wolfssl-wolfcrypt/tests/test_curve25519.rs | Updates Curve25519 tests for conditional RNG sharing when blinding is enabled. |
| wrapper/rust/wolfssl-wolfcrypt/tests/test_blake2_mac.rs | Adds MAC trait tests for BLAKE2b/BLAKE2s keyed constructions. |
| wrapper/rust/wolfssl-wolfcrypt/tests/test_blake2_digest.rs | Adds Digest trait tests for typed BLAKE2b/BLAKE2s hashers. |
| wrapper/rust/wolfssl-wolfcrypt/tests/test_aes.rs | Adds AES-192-GCM/CCM AEAD roundtrip tests. |
| wrapper/rust/wolfssl-wolfcrypt/src/rsa.rs | Refactors RSA RNG usage (&RNG params, owned/shared RNG binding stored to ensure lifetime). |
| wrapper/rust/wolfssl-wolfcrypt/src/rsa_pkcs1v15.rs | Updates RSA PKCS#1v1.5 signing wrapper to new RNG pointer model. |
| wrapper/rust/wolfssl-wolfcrypt/src/random.rs | Refactors RNG to own WC_RNG* allocated via wc_rng_new_ex, updates methods to take &self. |
| wrapper/rust/wolfssl-wolfcrypt/src/mlkem.rs | Updates ML-KEM APIs to accept &RNG and pass WC_RNG* through FFI. |
| wrapper/rust/wolfssl-wolfcrypt/src/lms.rs | Updates LMS keygen to accept &RNG. |
| wrapper/rust/wolfssl-wolfcrypt/src/lib.rs | Adds alloc support and conditionally exports new BLAKE2 digest/MAC modules. |
| wrapper/rust/wolfssl-wolfcrypt/src/hmac.rs | Implements deep Clone for HMAC via wc_HmacCopy. |
| wrapper/rust/wolfssl-wolfcrypt/src/hmac_mac.rs | Derives Clone for HMAC MAC wrapper types. |
| wrapper/rust/wolfssl-wolfcrypt/src/ed448.rs | Updates Ed448 key generation to accept &RNG. |
| wrapper/rust/wolfssl-wolfcrypt/src/ed25519.rs | Updates Ed25519 key generation to accept &RNG. |
| wrapper/rust/wolfssl-wolfcrypt/src/ecdsa.rs | Adapts ECDSA wrapper FFI calls to ECC key pointer storage changes. |
| wrapper/rust/wolfssl-wolfcrypt/src/ecc.rs | Refactors ECC to store a C-heap ecc_key* and adds owned/shared RNG binding. |
| wrapper/rust/wolfssl-wolfcrypt/src/dilithium.rs | Updates Dilithium APIs to accept &RNG. |
| wrapper/rust/wolfssl-wolfcrypt/src/dh.rs | Updates DH APIs to accept &RNG. |
| wrapper/rust/wolfssl-wolfcrypt/src/curve25519.rs | Updates Curve25519 APIs to accept &RNG, adds RNG ownership/sharing for blinding. |
| wrapper/rust/wolfssl-wolfcrypt/src/blake2_mac.rs | Adds RustCrypto Mac trait wrappers for keyed BLAKE2b/BLAKE2s. |
| wrapper/rust/wolfssl-wolfcrypt/src/blake2_digest.rs | Adds RustCrypto Digest trait wrappers for typed BLAKE2b/BLAKE2s hashers. |
| wrapper/rust/wolfssl-wolfcrypt/src/aes.rs | Adds AES-192 CCM/GCM AEAD wrappers. |
| wrapper/rust/wolfssl-wolfcrypt/Makefile | Enables the new alloc feature in the Makefile feature set. |
| wrapper/rust/wolfssl-wolfcrypt/Cargo.toml | Replaces std feature with alloc and keeps feature list in sync with new APIs/modules. |
Comments suppressed due to low confidence (1)
wrapper/rust/wolfssl-wolfcrypt/Cargo.toml:22
- This change removes the previously exported
stdfeature and adds a newallocfeature. Together with the public API signature changes in this PR (e.g.,set_rng/generatenow takingRNGor&RNGinstead of&mut RNG), this is a semver-breaking change for a 1.x crate. Consider either (a) bumping the crate major version, or (b) keepingstdas a backwards-compatible feature alias toallocand providing compatibility shims where practical.
[features]
alloc = []
rand_core = ["dep:rand_core"]
aead = ["dep:aead"]
cipher = ["dep:cipher"]
mac = ["digest/mac"]
digest = ["dep:digest"]
signature = ["dep:signature"]
password-hash = ["dep:password-hash", "password-hash/phc"]
kem = ["dep:kem", "hybrid-array/extra-sizes"]
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- store pointer to WC_RNG instead of full struct - enforce RNG is not dropped before consumer structs The C library stores a pointer via the set_rng() methods on a few structs (e.g. RSA). This change holds a reference (or instance) of RNG within the consumer structs to ensure it is kept alive if set_rng (or now set_shared_rng) is used.
This fixes internal pointers breaking if Rust moves the ECC struct (with some build configurations).
bb8cfde to
f8f17d0
Compare
| /// let dec_len = rsa.private_decrypt(&enc[0..enc_len], &mut plain_out).expect("Error with private_decrypt()"); | ||
| /// assert!(dec_len as usize == plain.len()); | ||
| /// assert_eq!(plain_out[0..dec_len], *plain); | ||
| /// } |
There was a problem hiding this comment.
All doc examples for set_rng and set_shared_rng now use Arc and are gated #[cfg(all(random, feature = "alloc"))]. A no_alloc caller has no example showing how to use the owned set_rng path (which is their only option). Please add a doc example for set_rng that does not require alloc.
| assert!(ECC::import_raw_ex(qx_no_nul, qy, d, ECC::SECP256R1, None, None).is_err()); | ||
| assert!(ECC::import_raw_ex(qx, qy_no_nul, d, ECC::SECP256R1, None, None).is_err()); | ||
| assert!(ECC::import_raw_ex(qx, qy, d_no_nul, ECC::SECP256R1, None, None).is_err()); | ||
| assert!(ECC::import_raw_ex(qx, qy, empty, ECC::SECP256R1, None, None).is_err()); |
There was a problem hiding this comment.
import_raw is tested with empty for both qx (line 389) and the curve-name slot (line 390), but import_raw_ex is only tested with empty for d (line 395). Missing: import_raw_ex(empty, qy, d, ...) and import_raw_ex(qx, empty, d, ...) — both presumably call the same underlying C code so they would pass, but the coverage is asymmetric with the import_raw checks above.
| let dev_id = match dev_id { | ||
| Some(dev_id) => dev_id, | ||
| None => sys::INVALID_DEVID, | ||
| pub fn generate(size: i32, rng: &RNG, heap: Option<*mut core::ffi::c_void>, dev_id: Option<i32>) -> Result<Self, i32> { |
There was a problem hiding this comment.
Many doc examples in ecc.rs still declare let mut rng = RNG::new() and pass &mut rng to generate(), generate_ex(), generate_ex2(), sign_hash(), make_pub(), make_pub_to_point(), etc. Those methods now take &RNG (shared reference), so mut on the binding and &mut at the call site are both unnecessary and will produce compiler warnings when doc-tests are run. Please drop the mut qualifier (e.g. let rng = RNG::new()) and change &mut rng to &rng throughout the untouched doc examples.
| /// Bind a shared `RNG` to this key. Available when the `alloc` feature | ||
| /// is enabled. | ||
| #[cfg(all(random, feature = "alloc"))] | ||
| pub fn set_shared_rng(&mut self, rng: alloc::sync::Arc<RNG>) -> Result<(), i32> { |
There was a problem hiding this comment.
The doc comment for set_shared_rng doesn't mention the !Sync constraint on RNG. Because RNG: !Sync, Arc<RNG> is also !Sync, so it cannot be shared between threads without a Mutex. Callers expecting to use the same RNG from multiple threads will need Arc<Mutex<RNG>>, but that type cannot be passed to set_shared_rng. The intended use case (sharing one RNG among multiple keys on the same thread) should be stated in the doc comment so callers aren't surprised when they try to move an Arc<RNG> to another thread.
Description
This PR includes several Fenrir fixes and some new functionality I found missing during my integration tests with boringtun.
See the commits for individual descriptions of each change.
Testing
Unit/CI tests.
Checklist