Skip to content

Add Hmac_DRBG#1382

Open
keks wants to merge 34 commits intomainfrom
keks/drbg
Open

Add Hmac_DRBG#1382
keks wants to merge 34 commits intomainfrom
keks/drbg

Conversation

@keks
Copy link
Copy Markdown
Member

@keks keks commented Apr 9, 2026

This PR adds a DRBG and a wrapper that allows it to implement rand::CryptoRng.

@keks keks requested review from a team as code owners April 9, 2026 14:08
@keks keks requested a review from jschneider-bensch April 9, 2026 14:08
Comment thread crates/algorithms/hmac-drbg/src/rand.rs
}

mod impl_hacl;
mod incremental;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We should update the docs around this new, not yet verified version.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Should include a changelog entry, too.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The changelog entry should be under an ### Added heading. (We started doing a bit more fine-grained tracking of the change categories at some point, but didn't adapt do the categorization for earlier versions retroactively.)

Comment thread crates/algorithms/drbg/Cargo.toml Outdated
Comment thread Cargo.toml
libcrux-secrets = { version = "=0.0.5", path = "crates/utils/secrets" }

# 3rd Party
rand = { version = "0.9", default-features = false }
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We may bump to 0.10 before merging this and need to update here then as well.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I've updated the dependabot PR for this here: #1385

Copy link
Copy Markdown
Collaborator

@jschneider-bensch jschneider-bensch left a comment

Choose a reason for hiding this comment

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

Just some initial comments on docs, will give it a more thorough review later.

Comment thread Cargo.toml Outdated
Comment thread crates/testing/kats/src/wycheproof/hmac.rs
Comment thread crates/algorithms/hmac-drbg/src/rand.rs
/// [`HmacDrbg::generate`]: crate::HmacDrbg::generate
#[derive(Debug, PartialEq)]
pub enum GenerateError {
/// The reseed counter has exceeded [`RESEED_INTERVAL`]; call `reseed` before generating.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
/// The reseed counter has exceeded [`RESEED_INTERVAL`]; call `reseed` before generating.
/// The reseed counter has exceeded [`RESEED_INTERVAL`](crate::RESEED_INTERVAL); call `reseed` before generating.

/// The reseed counter has exceeded [`RESEED_INTERVAL`]; call `reseed` before generating.
ReseedRequired,

/// The requested output length is zero or exceeds [`MAX_GENERATE_BYTES`].
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
/// The requested output length is zero or exceeds [`MAX_GENERATE_BYTES`].
/// The requested output length is zero or exceeds [`MAX_GENERATE_BYTES`](crate::MAX_GENERATE_BYTES).

/// `V ≠ V_old`; equality signals a catastrophic HMAC fixed-point.
/// - **Inter-call / T4** (AIS 20/31): each new block must differ from the last
/// block of the previous `generate` call.
/// - **RCT** (SP 800-90B §4.4.1): no run of ≥ [`RCT_C`] identical bytes.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The doc links here are broken if the health-tests feature is not enabled.

Comment thread crates/algorithms/drbg/src/lib.rs Outdated
Copy link
Copy Markdown
Collaborator

@jschneider-bensch jschneider-bensch left a comment

Choose a reason for hiding this comment

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

Still didn't look too closely at the health checks yet, but have enough comments on the rest.

Comment thread crates/algorithms/drbg/src/lib.rs Outdated
/// Requesting more returns [`GenerateError::RequestTooLarge`].
pub const MAX_GENERATE_BYTES: usize = 65_536;

/// Minimum entropy input length in bytes (SP 800-90A Table 2: security strength).
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Should we reference Table 1 here as well? That is where the justification is that a maximum designed security strength of 256 bits allows for instantiating all the lower security strengths as well. I found it a bit confusing since the concrete number stated here is not found in Table 2, which instead references another recommendation document for the security strength.

Comment thread crates/algorithms/drbg/src/lib.rs Outdated
Comment thread crates/algorithms/drbg/src/lib.rs Outdated

/// Instantiate an HMAC_DRBG from explicit entropy material (SP 800-90A §10.1.2.3).
///
/// - `entropy_input`: must contain at least [`MIN_ENTROPY_BYTES`] bytes of entropy.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We do check the length of the provided entropy with the health-tests feature, but should we maybe do it in any case since it's relatively inexpensive?

I see that we don't have Error variants for these checks conditions failing outside of the health-tests feature...

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I was thinking about this as well. This is how it's done in the standard and it was given to me like this by @franziskuskiefer, so I decided against changing it. I liked that the health check error was so opaque and didn't want to open it up. Maybe we can add the check to only run if we don't do the health checks? Then we only need the additional error variant in that case, and the error variants don't overlap.

We'll have to do the same changes in Reseed.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

yeah sounds reasonable to me.

Comment thread crates/algorithms/drbg/src/rand.rs Outdated
Comment thread crates/algorithms/hmac-drbg/src/rand.rs
for b in self.v.iter_mut() {
unsafe { core::ptr::write_volatile(b, 0) };
}
atomic::compiler_fence(atomic::Ordering::SeqCst);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

For my understanding: What's the purpose of this atomic::compiler_fence here?

Copy link
Copy Markdown
Member Author

@keks keks Apr 16, 2026

Choose a reason for hiding this comment

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

It tells the compiler to not move a read before the zeroization when it reorders for optimization.

I think.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I'm not sure about the reasoning here. From the documentation for std::sync::atomic::compiler_fence I understand that it applies to intra-thread synchronization only and for this to work the read/write operations should be atomic ones. But as far as I can tell we don't do any atomic reads. The write_volatile is guaranteed to not to be re-ordered wrt to other externally observable events but can not be considered atomic.

@franziskuskiefer What are the requirements for zeroization here?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is stupid zeroization. I'd be totally fine with dropping this here, or moving into a separate crate to allow zerization across crates at some point.


/// Block-level tests run on each generated V block.
///
/// - **Test 1** (NIST 800-90C §9.3.3): `new_block ≠ v_before` (HMAC fixed-point).
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Is that reference correct? I can't find section 9.3.3 in NIST SP-800-90C.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

It also is not in SP-800-90Ar1, or in the Health Test section of that document. Not sure where that came from.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@franziskuskiefer I think you added this. Do you remember?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Oh, that looks hallucinated. 800-90A §10.1.2 may be more appropriate here.

Copy link
Copy Markdown
Member Author

@keks keks Apr 22, 2026

Choose a reason for hiding this comment

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

That's the thing. I can't find the check anywhere in the document.Not in 10.1.2 and not in 11.3.

}

mod impl_hacl;
mod incremental;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Should include a changelog entry, too.

@jschneider-bensch jschneider-bensch added the waiting-on-author Status: This is awaiting some action from the author. label Apr 15, 2026
@keks
Copy link
Copy Markdown
Member Author

keks commented Apr 16, 2026

How do you all feel about renaming the crate and module to hmac_drbg? It seems DRBG would be the scheme/primitive, but the construction we put into the algorithms folder is HMAC_DRBG.

@jschneider-bensch
Copy link
Copy Markdown
Collaborator

How do you all feel about renaming the crate and module to hmac_drbg? It seems DRBG would be the scheme/primitive, but the construction we put into the algorithms folder is HMAC_DRBG.

That sounds reasonable 👍

@keks keks requested a review from jschneider-bensch April 16, 2026 15:53
@github-actions github-actions Bot dismissed stale reviews from jschneider-bensch and jschneider-bensch April 16, 2026 15:53

Review re-requested

@keks keks changed the title Add DRBG Add Hmac_DRBG Apr 27, 2026
@keks keks linked an issue Apr 27, 2026 that may be closed by this pull request
@jschneider-bensch
Copy link
Copy Markdown
Collaborator

@keks Are the remaining comments all related to health tests? If so, we could also address those in a follow up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

waiting-on-author Status: This is awaiting some action from the author.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add HMAC_DRBG

3 participants