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};