Skip to content

Commit ac56833

Browse files
pmaxhoganclaude
andcommitted
build(deps): bump rand to 0.10 and migrate RNG API usage
rand 0.8 -> 0.10 in driven-crypto (the only crate with a direct rand dep). API migration per the rand 0.9/0.10 changelogs: - `use rand::RngCore` -> `use rand::TryRng` (RngCore is a deprecated stub in rand_core 0.10; TryRng is the fallible base trait) - `rand::rngs::OsRng.fill_bytes(buf)` -> `rand::rngs::SysRng.try_fill_bytes(buf).expect(...)` (OsRng was renamed SysRng and re-exported from getrandom 0.4; it only exposes the fallible TryRng surface, and .expect() preserves rand 0.8's behavior of panicking inside OsRng::fill_bytes on entropy failure) Semantics preserved: every call site still fills raw byte buffers straight from the OS CSPRNG (getrandom); no generator, seeding, or distribution changes. chacha20poly1305 0.10 keeps its internal rand_core 0.6 pin via aead 0.5, which is fine - driven-crypto never passes an RNG into an aead API, so the two rand_core majors coexist. Supersedes #85. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014fLmkjpFkiuky72eLBijL4
1 parent ef1bf38 commit ac56833

4 files changed

Lines changed: 31 additions & 10 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/driven-crypto/Cargo.toml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ keyring = { workspace = true }
3434
# for the verify-on-upload comparison.
3535
md5 = { workspace = true }
3636
# `getrandom`-backed RNG for the per-file STREAM nonce, the wrapped-key
37-
# nonce, and fresh master / per-source key material (DESIGN s7.1). Pinned to
38-
# 0.8 to match `chacha20poly1305` 0.10's `rand_core` 0.6 `OsRng`.
39-
rand = "0.8"
37+
# nonce, and fresh master / per-source key material (DESIGN s7.1).
38+
# `chacha20poly1305` 0.10 pulls in `aead` 0.5's own `rand_core` 0.6 `OsRng`
39+
# internally, but this crate never calls an `aead`/`chacha20poly1305` API
40+
# that accepts a caller-supplied RNG (no `encrypt_in_place_with_rng` /
41+
# `KeyInit::generate_key`) - every call site here fills a raw byte buffer
42+
# directly via `RngCore`/`TryRngCore`, so the two `rand_core` major versions
43+
# never need to match.
44+
rand = "0.10"

crates/driven-crypto/src/content.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use chacha20poly1305::{
2525
KeyInit, XChaCha20Poly1305,
2626
};
2727
use md5::{Digest, Md5};
28-
use rand::RngCore;
28+
use rand::TryRng;
2929

3030
use crate::key::{SourceKey, XNONCE_LEN};
3131
use crate::CryptoError;
@@ -65,7 +65,13 @@ impl ContentEncryptorImpl {
6565
/// Builds an encryptor for one file with a freshly generated nonce.
6666
pub(crate) fn new(source_key: &SourceKey) -> Self {
6767
let mut nonce = [0u8; XNONCE_LEN];
68-
rand::rngs::OsRng.fill_bytes(&mut nonce);
68+
// `SysRng` (rand 0.10's OS RNG, re-exported from `getrandom`) is
69+
// fallible (`TryRng`, not the infallible `Rng`) since reading OS
70+
// entropy can fail. `.expect()` preserves rand 0.8's `OsRng::fill_bytes`
71+
// behavior, which panicked internally on the same failure.
72+
rand::rngs::SysRng
73+
.try_fill_bytes(&mut nonce)
74+
.expect("OS RNG (getrandom) failed to fill content nonce");
6975
let cipher = XChaCha20Poly1305::new(source_key.as_bytes().as_ref().into());
7076
let stream_nonce = GenericArray::from_slice(&nonce[..STREAM_NONCE_LEN]);
7177
Self {

crates/driven-crypto/src/key.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use chacha20poly1305::{
1010
aead::{Aead, KeyInit},
1111
XChaCha20Poly1305, XNonce,
1212
};
13-
use rand::RngCore;
13+
use rand::TryRng;
1414
use zeroize::{Zeroize, ZeroizeOnDrop};
1515

1616
use crate::CryptoError;
@@ -38,7 +38,13 @@ impl MasterKey {
3838
#[must_use]
3939
pub fn generate() -> Self {
4040
let mut bytes = [0u8; KEY_LEN];
41-
rand::rngs::OsRng.fill_bytes(&mut bytes);
41+
// See `content.rs::ContentEncryptorImpl::new` for why `SysRng` needs
42+
// `try_fill_bytes` + `.expect()`: it's rand 0.10's fallible OS RNG,
43+
// and `.expect()` preserves rand 0.8 `OsRng::fill_bytes`'s panic on
44+
// the same underlying failure.
45+
rand::rngs::SysRng
46+
.try_fill_bytes(&mut bytes)
47+
.expect("OS RNG (getrandom) failed to fill master key");
4248
Self(bytes)
4349
}
4450

@@ -78,7 +84,9 @@ impl MasterKey {
7884
pub fn wrap_source_key(&self, source_key: &SourceKey) -> Result<WrappedSourceKey, CryptoError> {
7985
let cipher = XChaCha20Poly1305::new(self.0.as_ref().into());
8086
let mut nonce_bytes = [0u8; XNONCE_LEN];
81-
rand::rngs::OsRng.fill_bytes(&mut nonce_bytes);
87+
rand::rngs::SysRng
88+
.try_fill_bytes(&mut nonce_bytes)
89+
.expect("OS RNG (getrandom) failed to fill wrap nonce");
8290
let nonce = XNonce::from_slice(&nonce_bytes);
8391
let ciphertext = cipher
8492
.encrypt(nonce, source_key.0.as_ref())
@@ -120,7 +128,9 @@ impl SourceKey {
120128
#[must_use]
121129
pub fn generate() -> Self {
122130
let mut bytes = [0u8; KEY_LEN];
123-
rand::rngs::OsRng.fill_bytes(&mut bytes);
131+
rand::rngs::SysRng
132+
.try_fill_bytes(&mut bytes)
133+
.expect("OS RNG (getrandom) failed to fill source key");
124134
Self(bytes)
125135
}
126136

0 commit comments

Comments
 (0)