ic_kdf/lib.rs
1//! # ic-kdf — key derivation
2//!
3//! * [`hkdf`] — RFC 5869 extract-and-expand (SP 800-56C two-step).
4//! * [`pbkdf2()`] — SP 800-132 password-based derivation.
5//! * [`kbkdf`] — SP 800-108 counter-mode KDF over HMAC.
6//! * [`argon2()`] — RFC 9106 memory-hard password hashing.
7//!
8//! The HMAC-based functions are generic over the instantiation, so the same
9//! code path serves SHA-256, SHA-384, SHA-512, and the SHA-3 family.
10//!
11//! ## Choosing between the two password KDFs
12//!
13//! [`pbkdf2()`] is the only *approved* option and is not memory-hard, so a GPU
14//! attacks it far faster than a CPU defends it. [`argon2()`] is memory-hard and
15//! is what RFC 9106 recommends, but is not FIPS-approved. If you have a FIPS
16//! obligation the choice is made for you; otherwise reach for Argon2id.
17//!
18//! ```
19//! use ic_kdf::hkdf::Hkdf;
20//! use ic_core::traits::Kdf;
21//! use ic_mac::HmacSha256;
22//!
23//! let mut key = [0u8; 32];
24//! Hkdf::<HmacSha256>::derive(b"input keying material", b"salt", b"app v1", &mut key)?;
25//! # Ok::<(), ic_core::Error>(())
26//! ```
27#![cfg_attr(not(feature = "std"), no_std)]
28#![forbid(unsafe_code)]
29#![deny(missing_docs)]
30#![warn(clippy::all)]
31
32// Argon2 needs a large contiguous arena, so it is the one KDF here that
33// requires an allocator — `alloc`, not the whole standard library, so it still
34// builds for bare-metal targets that provide a global allocator.
35extern crate alloc;
36
37pub mod argon2;
38pub mod hkdf;
39pub mod kbkdf;
40pub mod pbkdf2;
41
42pub use argon2::{argon2, Argon2Params, Variant};
43pub use hkdf::Hkdf;
44pub use kbkdf::kbkdf_counter;
45pub use pbkdf2::pbkdf2;
46
47/// Ontology identifiers for the KDFs this crate provides.
48pub const KDF_IDS: &[&str] = &[
49 "argon2id",
50 "hkdf-sha2-256",
51 "hkdf-sha2-384",
52 "hkdf-sha2-512",
53 "pbkdf2-hmac-sha2-256",
54 "pbkdf2-hmac-sha2-512",
55 "sp800-108-counter-hmac-sha2-256",
56];
57
58/// The SP 800-132 floor for PBKDF2 iterations in new deployments.
59///
60/// SP 800-132 sets 1 000 as an absolute minimum; OWASP and the CMVP guidance
61/// for modern hardware put the practical floor far higher. An agent that
62/// derives a password-based key below this is warned by
63/// [`pbkdf2::check_iterations`].
64pub const PBKDF2_MIN_RECOMMENDED_ITERATIONS: u32 = 600_000;