Skip to main content

crypt_io/kdf/
mod.rs

1//! Key Derivation Functions (KDF).
2//!
3//! Two algorithms ship in 0.6.0, addressing different needs:
4//!
5//! | Algorithm   | Purpose                                            | Speed         | Feature       |
6//! |-------------|----------------------------------------------------|---------------|---------------|
7//! | HKDF-SHA256 | Derive one-or-many subkeys from a high-entropy IKM | Fast (µs)     | `kdf-hkdf`    |
8//! | HKDF-SHA512 | Same, wider underlying digest                      | Fast (µs)     | `kdf-hkdf`    |
9//! | Argon2id    | Derive a key from a *password* (low-entropy input) | Slow (~100ms) | `kdf-argon2`  |
10//!
11//! # Which one do I want?
12//!
13//! - **HKDF** ([RFC 5869]) for deriving subkeys from a master key, a
14//!   shared secret from a key exchange, or anything else already
15//!   high-entropy. HKDF does *not* protect against weak inputs — feeding
16//!   it a password is a security mistake.
17//!
18//! - **Argon2id** ([RFC 9106]) for deriving a key from a password. The
19//!   memory-hardness and tuneable cost are what protect against
20//!   brute-force attempts; the slowness is the point.
21//!
22//! [RFC 5869]: https://datatracker.ietf.org/doc/html/rfc5869
23//! [RFC 9106]: https://datatracker.ietf.org/doc/html/rfc9106
24//!
25//! # Examples
26//!
27//! Deriving a 32-byte subkey from a master:
28//!
29//! ```
30//! # #[cfg(feature = "kdf-hkdf")] {
31//! use crypt_io::kdf;
32//! let master = [0x42u8; 32];
33//! let subkey = kdf::hkdf_sha256(&master, Some(b"salt"), b"app:session:v1", 32)?;
34//! assert_eq!(subkey.len(), 32);
35//! # }
36//! # Ok::<(), crypt_io::Error>(())
37//! ```
38//!
39//! Hashing and verifying a password:
40//!
41//! ```no_run
42//! # #[cfg(feature = "kdf-argon2")] {
43//! use crypt_io::kdf;
44//! let phc = kdf::argon2_hash(b"correct horse battery staple")?;
45//! assert!(kdf::argon2_verify(&phc, b"correct horse battery staple")?);
46//! assert!(!kdf::argon2_verify(&phc, b"wrong guess")?);
47//! # }
48//! # Ok::<(), crypt_io::Error>(())
49//! ```
50
51#[cfg(feature = "kdf-argon2")]
52mod argon2_impl;
53#[cfg(feature = "kdf-hkdf")]
54mod hkdf_impl;
55
56#[cfg(feature = "kdf-argon2")]
57pub use self::argon2_impl::{
58    ARGON2_DEFAULT_OUTPUT_LEN, ARGON2_DEFAULT_SALT_LEN, Argon2Params, argon2_hash,
59    argon2_hash_with_params, argon2_verify,
60};
61#[cfg(feature = "kdf-hkdf")]
62pub use self::hkdf_impl::{
63    HKDF_MAX_OUTPUT_SHA256, HKDF_MAX_OUTPUT_SHA512, hkdf_sha256, hkdf_sha512,
64};