Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@afiffon
Copy link
Owner

@afiffon afiffon commented Oct 24, 2025

Summary by CodeRabbit

  • New Features
    • Added configurable AES-CCM and AES-GCM encryption variants (feature-gated).
    • Added a no-encryption placeholder when encryption features are disabled.
  • Chores
    • Updated multiple cryptography dependencies to newer prerelease versions.
    • Workspace metadata updated (version, repository/homepage, authors).
    • Test container image reference updated.
  • Bug Fixes
    • CI workflow: lock-file removal step now actually deletes the lock file.
  • API Changes
    • Encryptor constructors accept raw key byte slices.
    • Async network client futures no longer require being Send.
  • Documentation
    • Updated README, docs links/issue references; license author formatting adjusted.

@afiffon afiffon linked an issue Oct 24, 2025 that may be closed by this pull request
@coderabbitai
Copy link

coderabbitai bot commented Oct 24, 2025

Walkthrough

CI now actually deletes Cargo.lock. Crypto dependency versions and feature graph in crates/smb/Cargo.toml were updated and encryption implementation moved into feature-gated modules (CCM/GCM/impls/disabled). Several crypto API changes applied; async SSPI send future lost Send; Authenticator gained a private async resolver helper.

Changes

Cohort / File(s) Summary
CI / Build
\.github/workflows/build.yml
"Remove lock file" step now runs rm Cargo.lock; Samba test service image updated to ghcr.io/afiffon/smb-tests:latest.
Workspace metadata & docs
Cargo.toml, README.md, LICENSE.md, .github/ISSUE_TEMPLATE/bug_report.md, crates/smb/docs/*
Workspace/package metadata (homepage, repository, authors, version) and various doc links/issue references updated to new repo/author display name.
Container test config
docker-compose.yml
Tests service image changed to ghcr.io/afiffon/smb-tests:latest.
Dependency updates
crates/smb/Cargo.toml, crates/smb-transport/Cargo.toml
Bumped sspi and many RustCrypto crates (hmac, sha2, crypto-common, aes, aes-gcm, cmac, ccm, aead, etc. — many to pre-release versions); RDMA dependency URL updated to new remote.
Encryption module rework
crates/smb/src/crypto/encryption.rs, crates/smb/src/crypto/encryption/impls.rs, crates/smb/src/crypto/encryption/disabled.rs, crates/smb/src/crypto/encryption/encrypt_ccm.rs, crates/smb/src/crypto/encryption/encrypt_gcm.rs
Removed trait method EncryptingAlgo::trim_nonce, removed in-file encryptor types/factory; added feature-gated modules: impls.rs (trim_nonce free fn, ENCRYPTING_ALGOS, make_encrypting_algo), encrypt_ccm.rs and encrypt_gcm.rs (CCM/GCM implementations and type aliases), and disabled.rs (stub when encryption disabled).
Signing / GMAC updates
crates/smb/src/crypto/signing.rs
Adapted to updated RustCrypto APIs: added KeyInit import, switched AeadMutInPlaceAeadInOut, replaced in-place APIs with inout variants and adjusted key initialization and empty-data handling.
KDF import adjustment
crates/smb/src/crypto/kbkdf.rs
Added KeyInit import to use updated HMAC initializer APIs; no API change.
Async SSPI client signature
crates/smb/src/session/sspi_network_client.rs
Removed Send bound from boxed future return type of AsyncNetworkClient::send in the async path (now Pin<Box<dyn Future<Output = Result<Vec<u8>>> + 'a>>).
Authenticator async flow
crates/smb/src/session/authenticator.rs
Added private async helper async fn _resolve_with_async_client(...) that runs the SSPI generator loop using a ReqwestNetworkClient; call site updated to use the helper in the async Kerberos path.

Sequence Diagram(s)

sequenceDiagram
  participant Caller
  participant SSPIClient
  Note over SSPIClient: send now returns a boxed Future\nwithout the Send bound (must remain on current executor)
  Caller->>SSPIClient: send(&mut, &NetworkRequest)
  SSPIClient-->>Caller: Pin<Box<dyn Future<Output=Result<Vec<u8>>> + 'a>>
  Caller->>Caller: await (cannot move across threads)
Loading
sequenceDiagram
  participant User
  participant EncryptImpl
  Note over EncryptImpl: nonce trimming is a free fn\nand encrypt/decrypt use inout APIs
  User->>EncryptImpl: make_encrypting_algo(algorithm, key: &[u8])
  User->>EncryptImpl: trim_nonce(algo, nonce)
  User->>EncryptImpl: encrypt_inout_detached(..., trimmed_nonce)
  EncryptImpl-->>User: ciphertext + tag
Loading
sequenceDiagram
  participant Auth
  participant Generator
  participant ReqwestClient
  Note over Auth: _resolve_with_async_client runs the generator\nloop and uses ReqwestClient for network ops
  Auth->>Generator: start generator
  loop Suspended
    Generator->>ReqwestClient: send request
    ReqwestClient-->>Generator: response
    Generator->>Generator: resume
  end
  Generator-->>Auth: Completed result
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Files/areas to review closely:

  • crates/smb/src/crypto/encryption.rs and new encryption modules (impls.rs, encrypt_ccm.rs, encrypt_gcm.rs, disabled.rs) — feature gating, trait changes, nonce handling, and factory logic.
  • crates/smb/Cargo.toml — many prerelease dependency bumps and altered feature graph.
  • crates/smb/src/crypto/signing.rs and crates/smb/src/crypto/kbkdf.rs — Aead and KeyInit API adaptations.
  • crates/smb/src/session/sspi_network_client.rs — removing Send from returned future; check executor assumptions.
  • crates/smb/src/session/authenticator.rs — new private async helper wiring in ReqwestNetworkClient.

Poem

🐇 I nudged the lock into the night,
I trimmed the nonce with gentle care,
New ciphers woke in featureed light,
A future stayed at home — not going anywhere,
I thumped once, then munched a carrot fair. 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 46.67% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The PR title "Bump SSPI to 0.18, resolved #136" accurately identifies a primary change in the changeset, where the SSPI dependency was updated from 0.16.1 to 0.18.0. The title also correctly references the issue being resolved (#136), which appears related to a Windows build failure based on the source branch name. While the changeset includes additional supporting changes such as encryption module refactoring, updates to other dependencies, and network client modifications, these changes are likely necessary adjustments to accommodate the SSPI 0.18 upgrade and work with its new APIs. The title is clear, specific, and directly captures the substantive primary change that motivated the pull request.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 136-bug-cant-build-on-windows

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@afiffon afiffon force-pushed the 136-bug-cant-build-on-windows branch from 26a2d67 to ac621bb Compare October 24, 2025 08:46
@afiffon afiffon enabled auto-merge (squash) October 24, 2025 08:46
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ed4468b and ac621bb.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (5)
  • .github/workflows/build.yml (1 hunks)
  • crates/smb/Cargo.toml (1 hunks)
  • crates/smb/src/crypto/encryption.rs (2 hunks)
  • crates/smb/src/crypto/signing.rs (1 hunks)
  • crates/smb/src/session/sspi_network_client.rs (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: build (windows-latest, stable)
  • GitHub Check: build (windows-latest, 1.85)
  • GitHub Check: test (multi_threaded)
  • GitHub Check: test (single_threaded)
  • GitHub Check: test (async)
🔇 Additional comments (4)
.github/workflows/build.yml (1)

92-92: Excellent fix! The lock file is now properly removed.

The previous version was only echoing the removal command instead of executing it. This fix ensures that builds correctly test against the latest compatible dependency versions, preventing breakage for users who build without a lock file.

crates/smb/src/crypto/signing.rs (1)

183-184: Acceptable targeted deprecation suppression.

The #[allow(deprecated)] annotation is appropriately scoped to just the deprecated Key::from_slice call. This is consistent with the deprecation handling in the encryption modules.

crates/smb/Cargo.toml (1)

45-45: I've encountered contradictory information. The crates.io API reports 0.18.0 as the latest version, but the web search couldn't locate published release documentation for it. Let me verify further:

Reject this dependency update: sspi version 0.18.0 does not exist on crates.io.

The latest published sspi version is 0.17.0 (released 9 days ago), not 0.18.0. The Cargo.toml specifies a non-existent version that will fail to build. Update to sspi 0.17.0 instead and verify it resolves the Windows build issue.

Likely an incorrect or invalid review comment.

crates/smb/src/session/sspi_network_client.rs (1)

55-55: Removal of Send bound is correct and intentional.

The original concern is based on an unverified assumption about the sspi 0.18.0 trait signature. The code at this PR stage compiles successfully, which confirms that the sspi 0.18.0 AsyncNetworkClient trait does not require Send. The futures are never spawned on multi-threaded runtimes—they are awaited sequentially within the authenticator's async flow (line 134 in authenticator.rs), so Send is not operationally necessary regardless.

Likely an incorrect or invalid review comment.

Comment on lines 112 to 113
#![allow(deprecated)] // Until RustCrypto ccm is bumped

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Acceptable temporary solution for deprecation warnings.

The module-level #![allow(deprecated)] annotation is appropriate for suppressing RustCrypto CCM deprecation warnings until the library is updated. However, ensure there's a plan to update or migrate away from the deprecated APIs in the future.

Consider tracking this technical debt. Would you like me to open an issue to track updating RustCrypto CCM when the deprecations are resolved?

🤖 Prompt for AI Agents
crates/smb/src/crypto/encryption.rs lines 112-113: the module-level
`#![allow(deprecated)]` is acceptable short-term but should be tracked and
narrowed; replace the broad module allowance by either applying
`#[allow(deprecated)]` only to the specific item(s)/imports that use the
deprecated RustCrypto CCM API or keep the module-level allow but add a clear
TODO with an issue reference to migrate off deprecated CCM; create/open a
tracking issue (or add the issue number) in the TODO, and ensure the comment
includes the intended migration target or version bump that will remove this
allow.

Comment on lines 226 to 227
#![allow(deprecated)] // Until RustCrypto ccm is bumped

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix the inconsistent comment.

The comment says "Until RustCrypto ccm is bumped" but this is in the encrypt_gcm module, not the CCM module. The comment should reference GCM instead.

Apply this diff to correct the comment:

-    #![allow(deprecated)] // Until RustCrypto ccm is bumped
+    #![allow(deprecated)] // Until RustCrypto gcm is bumped
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
#![allow(deprecated)] // Until RustCrypto ccm is bumped
#![allow(deprecated)] // Until RustCrypto gcm is bumped
🤖 Prompt for AI Agents
In crates/smb/src/crypto/encryption.rs around lines 226 to 227, the module-level
allow attribute comment incorrectly references "RustCrypto ccm" while this is
the encrypt_gcm module; update the comment to reference GCM (e.g., "Until
RustCrypto gcm is bumped") so it correctly reflects the GCM module and keeps the
allow-deprecated rationale accurate.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ac621bb and 8fb5236.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (2)
  • crates/smb/Cargo.toml (1 hunks)
  • crates/smb/src/crypto/signing.rs (5 hunks)
🔇 Additional comments (3)
crates/smb/src/crypto/signing.rs (2)

149-149: LGTM! Correct API migration to AeadInOut.

The import change from AeadMutInPlace to AeadInOut correctly aligns with the new aes-gcm 0.11.0-rc.1 API, as reflected in the updated encrypt_inout_detached call on line 223.


223-229: LGTM! Correct migration to encrypt_inout_detached API.

The update from encrypt_in_place_detached to encrypt_inout_detached with the corresponding parameter adjustments correctly implements the new AeadInOut API from aes-gcm 0.11.0-rc.1.

crates/smb/Cargo.toml (1)

45-45: Confirm the sspi 0.18.0 bump resolves the Windows build issue and check for breaking changes.

The version specification is correct—sspi 0.18.0 exists and was published on October 20, 2025. However, this is a significant bump from 0.16.1 (skipping 0.17.0) and I cannot access the detailed release notes to verify:

  • Whether this version actually resolves the Windows build issue (#136)
  • What breaking changes exist between 0.16.1 and 0.18.0

Please manually verify the Devolutions/sspi-rs GitHub releases page for 0.18.0 release notes and confirm that:

  1. The Windows build failure is fixed in this version
  2. Any breaking changes are compatible with this codebase

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
crates/smb/src/crypto/encryption.rs (2)

86-95: Avoid allocating the key for Aes256Gcm.

encrypting_key.into() creates a Vec and copies bytes unnecessarily. Pass the slice directly (like Aes128Gcm).

-        EncryptionCipher::Aes256Gcm => Ok(encrypt_gcm::Aes256GcmEncryptor::build(
-            encrypting_key.into(),
-        )?),
+        EncryptionCipher::Aes256Gcm => Ok(encrypt_gcm::Aes256GcmEncryptor::build(
+            encrypting_key,
+        )?),

208-215: Debug string is misleading for AES-256-CCM.

fmt always prints "Ccm128Encrypter" even when C is Aes256. Make it generic.

-            write!(f, "Ccm128Encrypter")
+            write!(f, "CcmEncrypter")
♻️ Duplicate comments (1)
crates/smb/Cargo.toml (1)

49-57: RC/pre-release crypto versions: use stable or document rationale.

These RCs can churn APIs and break consumers. Either pin to latest stable compatible versions or add a brief comment explaining why RCs are required (link issue/PR).

Option A (prefer): switch to stable. Option B: add rationale above these deps referencing the tracked issue.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8fb5236 and fe1833f.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (3)
  • crates/smb/Cargo.toml (1 hunks)
  • crates/smb/src/crypto/encryption.rs (13 hunks)
  • crates/smb/src/crypto/kbkdf.rs (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build (windows-latest, stable)
  • GitHub Check: build (windows-latest, 1.85)
🔇 Additional comments (1)
crates/smb/Cargo.toml (1)

45-45: SSPI bump to 0.18.0 looks good.

This aligns with the goal to fix Windows builds for issue #136. Please confirm CI covers Windows MSRV and cross-compilation.

Run (locally/CI): cargo check -p smb --features async,encrypt,sign --target x86_64-pc-windows-msvc

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
crates/smb/src/crypto/encryption.rs (1)

206-213: Debug fmt is misleading for AES-256 CCM.

This always prints "Ccm128Encrypter" regardless of C. Make output generic or reflect the cipher.

 impl<C> std::fmt::Debug for CcmEncryptor<C>
 where
     C: BlockCipherEncrypt + BlockSizeUser<BlockSize = U16> + BlockCipherDecrypt,
 {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        write!(f, "Ccm128Encrypter")
+        write!(f, "CcmEncryptor<{}>", std::any::type_name::<C>())
     }
 }
♻️ Duplicate comments (3)
crates/smb/src/crypto/encryption.rs (1)

42-51: Prevent runtime panic in trim_nonce; tie size to U and guard before try_from.

If algo.nonce_size() ever diverges from U, this unwrap will panic in release. Assert the expected size and slice to that length explicitly, then use expect with a clear message.

 fn trim_nonce<U: aead::array::ArraySize>(
     algo: &dyn EncryptingAlgo,
     nonce: &EncryptionNonce,
 ) -> aead::array::Array<u8, U> {
     // Sanity: the rest of the nonce is expected to be zero.
     debug_assert!(nonce[algo.nonce_size()..].iter().all(|&x| x == 0));
-    aead::array::Array::try_from(&nonce[..algo.nonce_size()]).unwrap()
+    let expected = <U as aead::array::ArraySize>::USIZE;
+    debug_assert_eq!(algo.nonce_size(), expected, "nonce size mismatch");
+    aead::array::Array::try_from(&nonce[..expected])
+        .expect("trim_nonce: nonce slice length must match algorithm nonce size")
 }
crates/smb/src/crypto/signing.rs (2)

69-69: Wrong/misleading KeyInit import in HMAC signer; remove or import from the correct crate.

This module doesn’t use CCM. Either drop KeyInit entirely (not needed for HMAC here) or import the proper trait (e.g., hmac::digest::KeyInit) if you rely on it.

-    use ccm::KeyInit;
+    // Not needed; remove. If required, prefer:
+    // use hmac::digest::KeyInit;

110-110: Wrong/misleading KeyInit import in CMAC signer; use the proper trait or remove.

CCM’s KeyInit doesn’t apply here. CMAC’s new_from_slice comes from the digest/crypto_common KeyInit trait.

-    use ccm::KeyInit;
+    // Prefer one of:
+    // use crypto_common::KeyInit;
+    // use cmac::digest::KeyInit;
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fe1833f and 38ba2aa.

📒 Files selected for processing (3)
  • crates/smb/src/crypto/encryption.rs (13 hunks)
  • crates/smb/src/crypto/signing.rs (5 hunks)
  • crates/smb/src/session/authenticator.rs (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
crates/smb/src/crypto/signing.rs (1)
crates/smb/src/session/signer.rs (1)
  • new (19-21)
crates/smb/src/crypto/encryption.rs (1)
crates/smb/src/crypto/signing.rs (3)
  • build (83-87)
  • build (120-124)
  • build (184-191)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build (windows-latest, stable)
  • GitHub Check: build (windows-latest, 1.85)
🔇 Additional comments (1)
crates/smb/src/session/authenticator.rs (1)

160-182: Async resolver looks correct; mirrors sspi-rs state machine.

Looping over Suspended → resume(send(request).await) and returning Completed is sound with the new SSPI 0.18 API.

If SSPI evolves additional GeneratorState variants, consider a non-exhaustive match to surface compile-time errors. Also verify ReqwestNetworkClient::send returns a Future that’s Send to keep this async fn Send.

Comment on lines 234 to 244
impl<T> AesGcmEncryptor<T>
where
T: BlockCipher<BlockSize = typenum::U16>
+ BlockEncrypt
+ KeyInit
T: BlockCipherEncrypt<BlockSize = typenum::U16>
+ BlockCipherDecrypt<BlockSize = typenum::U16>
+ KeySizeUser
+ KeyInit
+ Send
+ Clone
+ Sync
+ 'static,
{
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Unify GCM trait bounds; specify BlockSize for BlockCipherDecrypt too.

Be consistent and explicit on both Encrypt and Decrypt bounds to avoid accidental divergence.

 impl<T> AesGcmEncryptor<T>
 where
-    T: BlockCipherEncrypt<BlockSize = typenum::U16>
-        + BlockCipherDecrypt<BlockSize = typenum::U16>
+    T: BlockCipherEncrypt<BlockSize = typenum::U16>
+        + BlockCipherDecrypt<BlockSize = typenum::U16>
         + KeySizeUser
         + KeyInit
         + Send
         + Clone
         + Sync
         + 'static,
 { ... }

 impl<T> EncryptingAlgo for AesGcmEncryptor<T>
 where
-    T: BlockCipherEncrypt<BlockSize = typenum::U16>
-        + BlockCipherDecrypt
+    T: BlockCipherEncrypt<BlockSize = typenum::U16>
+        + BlockCipherDecrypt<BlockSize = typenum::U16>
         + KeyInit
         + KeySizeUser
         + Send
         + Clone
         + Sync
         + 'static,
 { ... }

Also applies to: 252-262

🤖 Prompt for AI Agents
In crates/smb/src/crypto/encryption.rs around lines 234-244 (and similarly
252-262), the impl trait bounds currently specify BlockCipherEncrypt with
BlockSize = typenum::U16 but omit the same BlockSize constraint on
BlockCipherDecrypt; update both impl blocks to include
BlockCipherDecrypt<BlockSize = typenum::U16> so the encrypt and decrypt trait
bounds are explicit and consistent, ensure the rest of the listed bounds
(KeySizeUser, KeyInit, Send, Clone, Sync, 'static) remain unchanged.

Comment on lines 220 to 227
let mut empty_data: Vec<u8> = vec![];
let result = self
.gmac
.encrypt_in_place_detached(
.encrypt_inout_detached(
self.nonce.get().unwrap().into(),
&self.buffer,
&mut empty_data,
empty_data.as_mut_slice().into(),
)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Avoid heap allocation for empty GMAC payload.

No need to allocate a Vec each finalize; use a zero-length stack slice.

-            let mut empty_data: Vec<u8> = vec![];
+            let mut empty: [u8; 0] = [];
             let result = self
                 .gmac
                 .encrypt_inout_detached(
                     self.nonce.get().unwrap().into(),
                     &self.buffer,
-                    empty_data.as_mut_slice().into(),
+                    empty.as_mut_slice().into(),
                 )
                 .unwrap();
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
let mut empty_data: Vec<u8> = vec![];
let result = self
.gmac
.encrypt_in_place_detached(
.encrypt_inout_detached(
self.nonce.get().unwrap().into(),
&self.buffer,
&mut empty_data,
empty_data.as_mut_slice().into(),
)
let mut empty: [u8; 0] = [];
let result = self
.gmac
.encrypt_inout_detached(
self.nonce.get().unwrap().into(),
&self.buffer,
empty.as_mut_slice().into(),
)
.unwrap();
🤖 Prompt for AI Agents
In crates/smb/src/crypto/signing.rs around lines 220 to 227, avoid allocating a
Vec<u8> for an empty GMAC payload; replace the heap allocation with a
zero-length stack buffer (e.g. a local [u8; 0]) and pass its mutable slice into
encrypt_inout_detached instead of empty_data.as_mut_slice(), keeping the same
call shape so types still match.

Comment on lines +133 to 138
Self::_resolve_with_async_client(
&mut generator,
&mut ReqwestNetworkClient::new(),
)
.await?
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Don’t instantiate a new ReqwestNetworkClient per call; reuse it.

Creating a client on every next() adds TLS pool overhead and hurts performance. Store a ReqwestNetworkClient inside Authenticator and reuse it across calls.

  • Add a field: network_client: Option
  • Initialize in build() behind the same cfg gates.
  • Pass &mut self.network_client.as_mut().unwrap() here.
🤖 Prompt for AI Agents
In crates/smb/src/session/authenticator.rs around lines 133 to 138, avoid
creating a new ReqwestNetworkClient on every call; instead add a field
network_client: Option<ReqwestNetworkClient> to Authenticator, initialize that
field in build() using the same cfg feature gates you currently use to construct
ReqwestNetworkClient, and in next() pass a mutable reference to the stored
client (e.g. &mut self.network_client.as_mut().unwrap()) into
Self::_resolve_with_async_client. Ensure the field is behind the same cfg
attributes and is created once in build(), and update usages to borrow the
stored client rather than constructing a new one.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
crates/smb/src/crypto/signing.rs (1)

218-225: Avoid heap allocation for empty GMAC payload.

This issue was flagged in a previous review but remains unaddressed. The Vec<u8> allocation on line 218 is unnecessary overhead—use a zero-length stack array instead.

Apply this diff to eliminate the heap allocation:

-            let mut empty_data: Vec<u8> = vec![];
+            let mut empty: [u8; 0] = [];
             let result = self
                 .gmac
                 .encrypt_inout_detached(
                     self.nonce.get().unwrap().into(),
                     &self.buffer,
-                    empty_data.as_mut_slice().into(),
+                    empty.as_mut_slice().into(),
                 )
                 .unwrap();
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 38ba2aa and f406687.

📒 Files selected for processing (12)
  • .github/ISSUE_TEMPLATE/bug_report.md (1 hunks)
  • .github/workflows/build.yml (2 hunks)
  • Cargo.toml (1 hunks)
  • LICENSE.md (1 hunks)
  • README.md (2 hunks)
  • crates/smb-transport/Cargo.toml (1 hunks)
  • crates/smb/docs/parallelize.md (1 hunks)
  • crates/smb/docs/threading_models.md (1 hunks)
  • crates/smb/src/crypto/kbkdf.rs (1 hunks)
  • crates/smb/src/crypto/signing.rs (5 hunks)
  • crates/smb/src/session/sspi_network_client.rs (2 hunks)
  • docker-compose.yml (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: build (windows-latest, stable)
  • GitHub Check: test (single_threaded)
  • GitHub Check: build (windows-latest, 1.85)
  • GitHub Check: test (async)
  • GitHub Check: test (multi_threaded)
🔇 Additional comments (15)
crates/smb/docs/parallelize.md (1)

40-40: Update looks good.

The GitHub issue reference is correctly updated from the old organization namespace to the new one, maintaining consistency with the broader repository migration mentioned in this PR.

crates/smb/src/session/sspi_network_client.rs (1)

55-55: Breaking change: Removed Send bound from async Future.

The removal of the + Send bound means this future can no longer be moved across threads, which is a breaking change for multi-threaded async contexts. Code that spawns this future on multi-threaded executors (e.g., tokio::spawn) will fail to compile.

Please verify this change aligns with the upstream sspi 0.18 AsyncNetworkClient trait requirements and consider documenting this breaking change in the PR description or changelog.

.github/ISSUE_TEMPLATE/bug_report.md (1)

6-6: LGTM!

The assignee update aligns with the repository namespace changes throughout this PR.

README.md (1)

3-3: LGTM!

The badge and project links have been correctly updated to reflect the new repository namespace.

Also applies to: 33-33

crates/smb/src/crypto/kbkdf.rs (1)

2-2: LGTM!

The KeyInit import from hmac is necessary for using HmacSha256::new_from_slice at line 70, which is part of the updated hmac 0.13.0-rc.2 API. This is distinct from the past review comment about the unused ccm::KeyInit import.

docker-compose.yml (1)

7-7: LGTM!

The test image reference has been correctly updated to match the new repository namespace.

crates/smb/docs/threading_models.md (1)

98-98: LGTM!

The documentation links have been correctly updated to reflect the new repository location.

crates/smb-transport/Cargo.toml (1)

35-35: LGTM!

Good practice to update the commented-out dependency URL for consistency, even though it has no current functional impact.

.github/workflows/build.yml (2)

31-31: LGTM!

The samba test image reference has been correctly updated to match the new repository namespace.


92-92: Good fix!

The step now actually removes Cargo.lock instead of just echoing the command. This aligns with the stated intent in the comment above (line 90) and ensures builds use the latest compatible dependency versions rather than locked versions.

crates/smb/src/crypto/signing.rs (4)

69-69: LGTM - KeyInit import corrected.

The KeyInit trait is now correctly imported from the hmac crate, addressing the previous review comment about importing it from the wrong source.


109-109: LGTM - KeyInit import corrected.

The KeyInit trait is now correctly imported from the cmac crate, addressing the previous review comment about importing it from the wrong source.


147-147: LGTM - Correct migration to new RustCrypto API.

The import update from AeadMutInPlace to AeadInOut correctly aligns with the aes-gcm 0.11.0-rc.1 API changes and the encrypt_inout_detached usage below.


183-185: LGTM - Correct key construction for new API.

The key construction correctly uses from(*key) to dereference the signing key and passes a reference to Aes128Gcm::new, aligning with the updated RustCrypto API.

Cargo.toml (1)

10-12: LGTM - Repository ownership metadata updated.

The homepage, repository URL, and author information have been updated to reflect the repository transfer to afiffon. These are metadata-only changes with no functional impact.

<!-- markdownlint-disable -->

Copyright 2025 AVIV NAAMAN
Copyright 2025 AVIV N
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

🧩 Analysis chain

Verify the copyright attribution change.

Modifying copyright holder attribution from "AVIV NAAMAN" to "AVIV N" may have legal implications. Copyright notices typically should reflect the actual legal name of the copyright holder and are not usually changed retroactively. Please confirm this change is intentional and legally appropriate.


</web_search>


🌐 Web query:

copyright holder name initials legal implications retroactive change

💡 Result:

Short answer: changing the name on a copyright (e.g., replacing full name with initials or vice‑versa) can usually be corrected, but doing so retroactively raises documentary, ownership, and standing risks—so correct and record the change promptly and get legal advice.

Key points

  • The U.S. Copyright Office will accept initials if they clearly identify the claimant (or the claimant is publicly known by those initials); otherwise the Office may add/annotate the full name or ask for clarification. (law.resource.org) [1]
  • Minor name-errors (including initials vs full name) that do not alter who actually owns the work are typically handled by corrective entries, amendments, or an affidavit for recordation; the Office explains when it will amend records or require an applicant communication. (en.wikisource.org) [2][1]
  • Retroactive corrections (nunc pro tunc) or re‑recording of assignments/registrations can often be made, but they can affect standing, chain of title, and third‑party reliance (and courts scrutinize retroactive changes in litigation). Fixes are easier if done promptly; older corrections can be more complicated. (blueovergray.com) [3][4]
  • Practical implications: until the public record clearly identifies the correct claimant, disputes over ownership, the right to sue for past infringement, licensing, or recording of assignments may arise. Always record corrections with the Copyright Office and, for assignments, re‑record corrected instruments; keep original signed evidence of who approved changes. (law.resource.org) [1][4]

If you want, tell me the jurisdiction (U.S. or other), whether this is a registration or an assignment, and the exact change (e.g., “J. Smith” → “John Smith”) and I’ll outline the concrete steps and language to record the correction.

Citations:


</web_search>


🌐 Web query:

LICENSE file copyright notice best practices standard format

💡 Result:

Short answer — best practice:

  • Put the full license text in a top-level LICENSE file and add a concise copyright notice immediately above it (or at top of the repository/README/COPYRIGHT). Use a clear, consistent format: year or year-range, copyright symbol/word, and the copyright holder name. [1][2][5]

  • Make copyright notices machine-readable where practical (SPDX/REUSE): prefer lines like

    • Copyright (c) 2023 Acme Corp.
    • or SPDX-FileCopyrightText: 2023 Acme Corp. [email protected]
      and add an SPDX short identifier for the license (SPDX-License-Identifier: MIT). Use year ranges (2018–2023) when appropriate and list multiple holders on separate lines. [1][2][6]
  • Keep copyright text minimal and unmodified from original authors when bundling third‑party code; record original notices separately (NOTICE/COPYRIGHT or SPDX metadata). Many tools ignore copyright text when matching license bodies, so store metadata in SPDX/DEP5/.reuse when needed. [3][4][2]

Minimal examples you can copy:

  • In LICENSE (above the license body):
    Copyright (c) 2021–2025 Acme Corporation
    <then full license text — e.g., MIT, Apache-2.0, etc.>. [5][1]

  • In source-file header (optional / recommended for many licenses):
    // SPDX-License-Identifier: MIT
    // Copyright (c) 2025 Acme Corporation [email protected]
    (or use SPDX-FileCopyrightText in DEP5/.reuse). [6][2]

References

  1. SPDX — Handling license info and copyright guidance. [SPDX]. [turn0search6].
  2. REUSE spec — required copyright formatting and examples. [turn0search5].
  3. SPDX specification — copyright-notice guidelines. [turn0search0].
  4. Apache guidance on copyright notices and NOTICE vs LICENSE. [turn0search1].
  5. NIST / repository LICENSE recommendations (examples for top-level LICENSE, multiple licenses). [turn0search3].

Use full copyright holder name in LICENSE file for clarity and best practices.

While initials can technically identify a copyright holder, best practice for LICENSE files is to use the full copyright holder name for clarity and consistency. Changing "AVIV NAAMAN" to "AVIV N" deviates from this standard. Use the full legal name for formality and machine-readability.

🤖 Prompt for AI Agents
In LICENSE.md around line 3, the copyright holder is listed as "AVIV N" but
should use the full legal name; replace "AVIV N" with "AVIV NAAMAN" on that line
(and ensure any other occurrences in the LICENSE file match the full name for
consistency).

split encryption to some modules for convenience
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 11

♻️ Duplicate comments (1)
crates/smb/Cargo.toml (1)

48-57: RC/pre-release crypto deps: justify or split from SSPI bump.

These upgrades expand PR scope and may add churn. Either document the necessity (API compatibility, Windows fix) or move to a separate PR; otherwise use latest stable equivalents.

#!/bin/bash
# Check available stable versions on crates.io for the RC deps
for c in hmac sha2 crypto-common aes aes-gcm cmac ccm aead; do
  echo -n "$c stable: "
  curl -s "https://crates.io/api/v1/crates/$c" | jq -r '.crate.max_stable_version // "none"'
done
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f406687 and 234d877.

📒 Files selected for processing (6)
  • crates/smb/Cargo.toml (2 hunks)
  • crates/smb/src/crypto/encryption.rs (2 hunks)
  • crates/smb/src/crypto/encryption/disabled.rs (1 hunks)
  • crates/smb/src/crypto/encryption/encrypt_ccm.rs (1 hunks)
  • crates/smb/src/crypto/encryption/encrypt_gcm.rs (1 hunks)
  • crates/smb/src/crypto/encryption/impls.rs (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (4)
crates/smb/src/crypto/encryption/encrypt_gcm.rs (3)
crates/smb/src/crypto/encryption/encrypt_ccm.rs (6)
  • build (40-44)
  • encrypt (57-71)
  • decrypt (73-89)
  • nonce_size (91-93)
  • clone_box (95-97)
  • fmt (104-106)
crates/smb/src/crypto/encryption.rs (4)
  • encrypt (15-20)
  • decrypt (23-29)
  • nonce_size (32-32)
  • clone_box (39-39)
crates/smb/src/crypto/encryption/impls.rs (1)
  • trim_nonce (8-15)
crates/smb/src/crypto/encryption/impls.rs (4)
crates/smb/src/crypto/encryption.rs (1)
  • nonce_size (32-32)
crates/smb/src/crypto/encryption/encrypt_ccm.rs (2)
  • nonce_size (91-93)
  • build (40-44)
crates/smb/src/crypto/encryption/encrypt_gcm.rs (2)
  • nonce_size (78-80)
  • build (28-32)
crates/smb/src/crypto/encryption/disabled.rs (1)
  • make_encrypting_algo (8-15)
crates/smb/src/crypto/encryption/encrypt_ccm.rs (3)
crates/smb/src/crypto/encryption/encrypt_gcm.rs (6)
  • build (28-32)
  • encrypt (46-59)
  • decrypt (61-76)
  • nonce_size (78-80)
  • clone_box (82-84)
  • fmt (88-90)
crates/smb/src/crypto/encryption.rs (4)
  • encrypt (15-20)
  • decrypt (23-29)
  • nonce_size (32-32)
  • clone_box (39-39)
crates/smb/src/crypto/encryption/impls.rs (1)
  • trim_nonce (8-15)
crates/smb/src/crypto/encryption/disabled.rs (1)
crates/smb/src/crypto/encryption/impls.rs (1)
  • make_encrypting_algo (32-68)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: build (windows-latest, 1.85)
  • GitHub Check: test (multi_threaded)
  • GitHub Check: build (windows-latest, stable)
  • GitHub Check: test (async)
  • GitHub Check: test (single_threaded)
🔇 Additional comments (10)
crates/smb/src/crypto/encryption/disabled.rs (1)

8-15: Factory correctly rejects all algorithms in disabled mode.

Behavior is clear and matches the feature-gated design. LGTM.

crates/smb/src/crypto/encryption/impls.rs (1)

48-67: Factory and feature gating look correct.

The pre-check against ENCRYPTING_ALGOS and feature-gated constructors are clean. LGTM.

Please run cargo features audit locally to ensure no unreachable arms remain across all feature combos.

crates/smb/src/crypto/encryption/encrypt_gcm.rs (1)

46-76: Core encrypt/decrypt path looks correct.

In-place AEAD with detached tag, nonce trimming to 12 bytes, and little‑endian tag conversion align with CCM implementation. LGTM.

Please confirm SMB spec requires LE for tag serialization here, as with CCM.

crates/smb/src/crypto/encryption.rs (2)

3-3: Good: narrowed import to EncryptionNonce.

Reduces unnecessary symbols from smb_msg.


53-56: Module gating looks right.

CCM/GCM modules are feature-scoped; aligns with the new factory design.

crates/smb/Cargo.toml (2)

45-45: SSPI 0.18 bump with ring feature looks good.

Matches the PR goal to fix Windows build (#136). Please confirm CI runs a Windows job.


99-106: Feature graph for encryption is coherent.

__encrypt_core split and granular CCM/GCM flags make sense. LGTM.

Consider running cargo hack or a feature matrix locally to ensure all combos build.

crates/smb/src/crypto/encryption/encrypt_ccm.rs (3)

1-14: LGTM! Imports are correctly feature-gated.

The conditional imports for Aes128 and Aes256 align with their respective feature flags, while shared cipher traits remain unconditionally available for the generic implementation.


19-25: LGTM! Struct definition is correct.

The generic CcmEncryptor<C> with Ccm<C, U16, U11> uses appropriate parameters: 16-byte block size for AES and 11-byte nonce (within CCM's valid 7-13 byte range).


27-98: LGTM! Implementation follows established patterns.

The build constructor and EncryptingAlgo trait implementation correctly mirror the GCM variant's structure. Nonce handling via trim_nonce, 11-byte nonce size (matching U11), and signature conversion to/from little-endian u128 are all appropriate for CCM mode.

Comment on lines +42 to +50
#[cfg(feature = "__encrypt_core")]
mod impls;
#[cfg(feature = "__encrypt_core")]
pub use impls::*;

/// A factory method that instantiates a [`EncryptingAlgo`] implementation
/// based on the provided encryption algorithm and key.
pub fn make_encrypting_algo(
encrypting_algorithm: EncryptionCipher,
encrypting_key: &[u8],
) -> Result<Box<dyn EncryptingAlgo>, CryptoError> {
if !ENCRYPTING_ALGOS.contains(&encrypting_algorithm) {
return Err(CryptoError::UnsupportedEncryptionAlgorithm(
encrypting_algorithm,
));
}
if cfg!(feature = "__debug-dump-keys") {
log::debug!(
"Using encryption algorithm {:?} with key {:02x?}",
encrypting_algorithm,
encrypting_key
);
}
match encrypting_algorithm {
#[cfg(feature = "encrypt_aes128ccm")]
EncryptionCipher::Aes128Ccm => Ok(encrypt_ccm::Aes128CcmEncryptor::build(
encrypting_key.into(),
)?),
#[cfg(feature = "encrypt_aes256ccm")]
EncryptionCipher::Aes256Ccm => Ok(encrypt_ccm::Aes256CcmEncryptor::build(
encrypting_key.into(),
)?),
#[cfg(feature = "encrypt_aes128gcm")]
EncryptionCipher::Aes128Gcm => Ok(encrypt_gcm::Aes128GcmEncryptor::build(
encrypting_key.into(),
)?),
#[cfg(feature = "encrypt_aes256gcm")]
EncryptionCipher::Aes256Gcm => Ok(encrypt_gcm::Aes256GcmEncryptor::build(
encrypting_key.into(),
)?),
#[cfg(not(all(
feature = "encrypt_aes128ccm",
feature = "encrypt_aes256ccm",
feature = "encrypt_aes128gcm",
feature = "encrypt_aes256gcm"
)))]
_ => Err(CryptoError::UnsupportedEncryptionAlgorithm(
encrypting_algorithm,
)),
}
}
#[cfg(not(feature = "__encrypt_core"))]
mod disabled;
#[cfg(not(feature = "__encrypt_core"))]
pub use disabled::*;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Prefer explicit re-exports over glob.

Expose only the intended public API to prevent accidental future expansion.

 #[cfg(feature = "__encrypt_core")]
 mod impls;
 #[cfg(feature = "__encrypt_core")]
-pub use impls::*;
+pub use impls::{ENCRYPTING_ALGOS, make_encrypting_algo};
 
 #[cfg(not(feature = "__encrypt_core"))]
 mod disabled;
 #[cfg(not(feature = "__encrypt_core"))]
-pub use disabled::*;
+pub use disabled::{ENCRYPTING_ALGOS, make_encrypting_algo};
🤖 Prompt for AI Agents
In crates/smb/src/crypto/encryption.rs around lines 42 to 50, the module
currently re-exports everything from impls and disabled with glob imports (pub
use impls::* / pub use disabled::*); replace these glob re-exports with explicit
re-exports of only the intended public items (e.g. pub use
impls::{EncryptionKey, encrypt, decrypt};) and do the same for the disabled
branch, listing the exact types/functions/constants to expose so the public API
is explicit and cannot accidentally expand; update both cfg(feature =
"__encrypt_core") and cfg(not(feature = "__encrypt_core")) blocks accordingly.

@@ -0,0 +1,15 @@
//! Placeholder module to be used when all encryption features are disabled.
use super::*;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Avoid wildcard import in public modules.

Import only what’s used for clarity and to prevent accidental name exposure.

-use super::*;
+use super::EncryptingAlgo;

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In crates/smb/src/crypto/encryption/disabled.rs around line 2, replace the
wildcard import `use super::*;` with explicit imports of only the symbols this
module uses; scan the file for all references to items from the parent module
and list them (e.g., types, traits, functions, constants) in a single `use
super::{...};` statement, removing any unused names and ensuring public exports
remain correct.

use crate::crypto::CryptoError;
use smb_msg::EncryptionCipher;

pub const ENCRYPTING_ALGOS: &[EncryptionCipher] = &[];
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Document the empty algorithm list.

Make intent explicit for readers when encryption is disabled.

+/// No encryption algorithms are available when encryption features are disabled.
 pub const ENCRYPTING_ALGOS: &[EncryptionCipher] = &[];
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
pub const ENCRYPTING_ALGOS: &[EncryptionCipher] = &[];
/// No encryption algorithms are available when encryption features are disabled.
pub const ENCRYPTING_ALGOS: &[EncryptionCipher] = &[];
🤖 Prompt for AI Agents
In crates/smb/src/crypto/encryption/disabled.rs around line 6, the public
constant ENCRYPTING_ALGOS is an empty slice but lacks documentation; add a Rust
doc comment (///) immediately above the const that clearly states this list is
intentionally empty because encryption is disabled in this build/feature flag
and that callers should not attempt to use any cipher when this module is
compiled; keep the comment brief and explicit so readers and generated docs
understand the intent.

Comment on lines +16 to +17
pub type Aes128CcmEncryptor = CcmEncryptor<Aes128>;
pub type Aes256CcmEncryptor = CcmEncryptor<Aes256>;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Feature-gate the type aliases to prevent compilation errors.

These type aliases reference Aes128 and Aes256, which are only imported when their respective features are enabled (lines 1-4). Without feature guards, compilation will fail when the features are disabled.

Apply this diff to fix the issue:

+#[cfg(feature = "encrypt_aes128ccm")]
 pub type Aes128CcmEncryptor = CcmEncryptor<Aes128>;
+#[cfg(feature = "encrypt_aes256ccm")]
 pub type Aes256CcmEncryptor = CcmEncryptor<Aes256>;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
pub type Aes128CcmEncryptor = CcmEncryptor<Aes128>;
pub type Aes256CcmEncryptor = CcmEncryptor<Aes256>;
#[cfg(feature = "encrypt_aes128ccm")]
pub type Aes128CcmEncryptor = CcmEncryptor<Aes128>;
#[cfg(feature = "encrypt_aes256ccm")]
pub type Aes256CcmEncryptor = CcmEncryptor<Aes256>;
🤖 Prompt for AI Agents
In crates/smb/src/crypto/encryption/encrypt_ccm.rs around lines 16-17, the type
aliases Aes128CcmEncryptor and Aes256CcmEncryptor reference Aes128 and Aes256
which are only imported under their feature flags; add feature guards to each
alias to avoid compilation when those features are disabled by placing
#[cfg(feature = "aes128")] immediately above the Aes128CcmEncryptor type alias
and #[cfg(feature = "aes256")] immediately above the Aes256CcmEncryptor type
alias so each alias is only compiled when its corresponding AES feature is
enabled.

Comment on lines +100 to +107
impl<C> std::fmt::Debug for CcmEncryptor<C>
where
C: BlockCipherEncrypt + BlockSizeUser<BlockSize = U16> + BlockCipherDecrypt,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Ccm128Encrypter")
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix misleading Debug output.

The hardcoded "Ccm128Encrypter" string is misleading because this Debug impl is generic over C and applies to both AES-128 and AES-256 variants. The "128" suffix incorrectly implies it's AES-128 specific.

Apply this diff to use a generic name:

 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-    write!(f, "Ccm128Encrypter")
+    write!(f, "CcmEncryptor")
 }

Alternatively, if you need to distinguish variants, consider using std::any::type_name::<C>() to show the actual cipher type.

🤖 Prompt for AI Agents
In crates/smb/src/crypto/encryption/encrypt_ccm.rs around lines 100 to 107, the
Debug impl returns a hardcoded "Ccm128Encrypter" which is misleading for generic
CcmEncryptor<C>; change the output to a generic identifier (e.g.,
"CcmEncryptor") or include the concrete cipher type by using
std::any::type_name::<C>() to reflect AES-128 vs AES-256; update the write! call
accordingly so Debug no longer implies a specific key size.

Comment on lines +37 to +44
T: BlockCipherEncrypt<BlockSize = typenum::U16>
+ BlockCipherDecrypt
+ KeyInit
+ KeySizeUser
+ Send
+ Clone
+ Sync
+ 'static,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Unify trait bounds: specify BlockSize for Decrypt too.

Keep Encrypt/Decrypt bounds consistent to avoid accidental divergence.

-    T: BlockCipherEncrypt<BlockSize = typenum::U16>
-        + BlockCipherDecrypt
+    T: BlockCipherEncrypt<BlockSize = typenum::U16>
+        + BlockCipherDecrypt<BlockSize = typenum::U16>
         + KeyInit
         + KeySizeUser
         + Send
         + Clone
         + Sync
         + 'static,
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
T: BlockCipherEncrypt<BlockSize = typenum::U16>
+ BlockCipherDecrypt
+ KeyInit
+ KeySizeUser
+ Send
+ Clone
+ Sync
+ 'static,
T: BlockCipherEncrypt<BlockSize = typenum::U16>
BlockCipherDecrypt<BlockSize = typenum::U16>
KeyInit
KeySizeUser
Send
Clone
Sync
'static,
🤖 Prompt for AI Agents
In crates/smb/src/crypto/encryption/encrypt_gcm.rs around lines 37 to 44, the
trait bounds list specifies BlockSize = typenum::U16 for BlockCipherEncrypt but
not for BlockCipherDecrypt; update the BlockCipherDecrypt bound to also include
BlockSize = typenum::U16 so both encrypt and decrypt bounds are consistent
(i.e., change BlockCipherDecrypt to BlockCipherDecrypt<BlockSize =
typenum::U16>), keeping the rest of the trait bounds unchanged.

Comment on lines +87 to +91
impl<T> std::fmt::Debug for AesGcmEncryptor<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "AesGcmEncrypter")
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Debug name typo.

Type is Encryptor but Debug prints “Encrypter”.

-        write!(f, "AesGcmEncrypter")
+        write!(f, "AesGcmEncryptor")
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
impl<T> std::fmt::Debug for AesGcmEncryptor<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "AesGcmEncrypter")
}
}
impl<T> std::fmt::Debug for AesGcmEncryptor<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "AesGcmEncryptor")
}
}
🤖 Prompt for AI Agents
In crates/smb/src/crypto/encryption/encrypt_gcm.rs around lines 87 to 91, the
Debug impl prints "AesGcmEncrypter" which mismatches the type name
AesGcmEncryptor; update the write! call to output "AesGcmEncryptor" (or
otherwise match the exact type name) so the Debug representation correctly
reflects the type.

@@ -0,0 +1,68 @@
use crypto_common::array::{Array, ArraySize};
use smb_msg::*;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Replace wildcard import with explicit types.

Keeps the surface tight and avoids accidental pulls from smb_msg.

-use smb_msg::*;
+use smb_msg::{EncryptionCipher, EncryptionNonce};
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
use smb_msg::*;
use smb_msg::{EncryptionCipher, EncryptionNonce};
🤖 Prompt for AI Agents
In crates/smb/src/crypto/encryption/impls.rs around line 2, replace the wildcard
import "use smb_msg::*" with explicit imports of only the symbols actually used
in this file: inspect the file to determine which
structs/enums/constants/functions are referenced from smb_msg, then change the
import to "use smb_msg::{TypeA, TypeB, function_c, CONST_D};" (listing the real
identifiers you find), remove any unused imports, and run cargo check to ensure
there are no missing symbols — this tightens the surface area and prevents
accidental pulls from smb_msg.

Comment on lines +8 to +15
pub(crate) fn trim_nonce<U: ArraySize>(
algo: &dyn EncryptingAlgo,
nonce: &EncryptionNonce,
) -> Array<u8, U> {
// Sanity: the rest of the nonce is expected to be zero.
debug_assert!(nonce[algo.nonce_size()..].iter().all(|&x| x == 0));
Array::try_from(&nonce[..algo.nonce_size()]).unwrap()
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Harden trim_nonce to avoid release panics and assert size agreement.

Unwrap can panic in release if algo.nonce_size() ever diverges from U. Assert the size and use expect with a clear message.

 pub(crate) fn trim_nonce<U: ArraySize>(
     algo: &dyn EncryptingAlgo,
     nonce: &EncryptionNonce,
 ) -> Array<u8, U> {
     // Sanity: the rest of the nonce is expected to be zero.
-    debug_assert!(nonce[algo.nonce_size()..].iter().all(|&x| x == 0));
-    Array::try_from(&nonce[..algo.nonce_size()]).unwrap()
+    debug_assert!(nonce[algo.nonce_size()..].iter().all(|&x| x == 0));
+    let expected = <U as ArraySize>::USIZE;
+    debug_assert_eq!(algo.nonce_size(), expected, "nonce size mismatch");
+    Array::try_from(&nonce[..expected])
+        .expect("trim_nonce: nonce slice length must match algorithm nonce size")
 }

Based on past review comments.

🤖 Prompt for AI Agents
In crates/smb/src/crypto/encryption/impls.rs around lines 8 to 15, the function
trim_nonce currently uses unwrap() which can panic in release if
algo.nonce_size() does not match the Array size; replace this with a runtime
check asserting the sizes match (e.g. assert_eq!(algo.nonce_size(), U::USIZE,
"...") with a clear message) and then replace unwrap() with expect("clear
message indicating the nonce size mismatch/failed conversion") on the try_from
result so failures provide a descriptive error rather than an opaque panic.

Comment on lines +41 to +47
if cfg!(feature = "__debug-dump-keys") {
log::debug!(
"Using encryption algorithm {:?} with key {:02x?}",
encrypting_algorithm,
encrypting_key
);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Don’t log raw keys, even under a debug feature.

If you must log, limit to length and a tiny prefix; never full material. This reduces accidental leakage if the feature is enabled.

-    if cfg!(feature = "__debug-dump-keys") {
-        log::debug!(
-            "Using encryption algorithm {:?} with key {:02x?}",
-            encrypting_algorithm,
-            encrypting_key
-        );
-    }
+    if cfg!(feature = "__debug-dump-keys") {
+        let prefix_len = encrypting_key.len().min(4);
+        log::debug!(
+            "Using encryption algorithm {:?} (key_len={}, key_prefix={:02x?})",
+            encrypting_algorithm,
+            encrypting_key.len(),
+            &encrypting_key[..prefix_len]
+        );
+    }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if cfg!(feature = "__debug-dump-keys") {
log::debug!(
"Using encryption algorithm {:?} with key {:02x?}",
encrypting_algorithm,
encrypting_key
);
}
if cfg!(feature = "__debug-dump-keys") {
let prefix_len = encrypting_key.len().min(4);
log::debug!(
"Using encryption algorithm {:?} (key_len={}, key_prefix={:02x?})",
encrypting_algorithm,
encrypting_key.len(),
&encrypting_key[..prefix_len]
);
}
🤖 Prompt for AI Agents
In crates/smb/src/crypto/encryption/impls.rs around lines 41-47 the code logs
the entire encryption key under the debug feature; change the debug logging to
never print full key material and instead log only safe metadata: the algorithm,
the key length, and a short hex prefix (e.g. first 2–4 bytes) of the key. Keep
the cfg!(feature = "__debug-dump-keys") guard, extract a tiny slice for the
prefix, and ensure you do not include the rest of the key in the log message.

@afiffon afiffon merged commit b449336 into main Oct 29, 2025
9 checks passed
@afiffon afiffon deleted the 136-bug-cant-build-on-windows branch October 29, 2025 14:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: Can't build on Windows

2 participants