This design document describes the implementation of configurable number of iteration (rounds) for PBKDF2 password hashing schemes in 389 Directory Server. The feature adds the ability to customize the computational cost of password hashing through a new attribute nsslapd-pwdPBKDF2NumIterations
and associated configuration mechanisms.
PBKDF2 (Password-Based Key Derivation Function 2) is a key stretching algorithm that makes password hashing more resistant to brute-force attacks by applying a cryptographic hash function repeatedly. The number of iterations directly affects the computational cost and security level of the password hashing process. As computing power increases over time, the ability to adjust iteration counts becomes crucial for maintaining security against evolving threats.
attributeTypes: ( 2.16.840.1.113730.3.1.2400
NAME 'nsslapd-pwdPBKDF2NumIterations'
DESC '389 Directory Server defined attribute type'
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
SINGLE-VALUE )
objectClasses: ( 2.16.840.1.113730.3.2.340
NAME 'pwdPBKDF2PluginConfig'
DESC 'PBKDF2 Password Storage Plugin configuration'
SUP top
MAY ( nsslapd-pwdPBKDF2NumIterations ) )
The objectClass is given to (and intended for) cn=PBKDF2-*,cn=Password Storage Schemes,cn=plugins,cn=config
entries.
These defaults and limits ensure a baseline security level and guard against extreme performance degradation.
static PBKDF2_ROUNDS: AtomicUsize = AtomicUsize::new(DEFAULT_PBKDF2_ROUNDS);
static PBKDF2_ROUNDS_SHA1: AtomicUsize = AtomicUsize::new(DEFAULT_PBKDF2_ROUNDS);
static PBKDF2_ROUNDS_SHA256: AtomicUsize = AtomicUsize::new(DEFAULT_PBKDF2_ROUNDS);
static PBKDF2_ROUNDS_SHA512: AtomicUsize = AtomicUsize::new(DEFAULT_PBKDF2_ROUNDS);
Each variant (SHA-1, SHA-256, SHA-512) can have its iteration count stored atomically for thread-safe access.
fn handle_pbkdf2_rounds_config(pb: &mut PblockRef, digest: MessageDigest) -> Result<(), PluginError> {
// Read configuration from the directory entry
// Validate and store the new iteration value with set_pbkdf2_rounds() call
// Log configuration changes
}
fn set_pbkdf2_rounds(digest: MessageDigest, rounds: usize) -> Result<(), PluginError> {
if rounds < MIN_PBKDF2_ROUNDS || rounds > MAX_PBKDF2_ROUNDS {
return Err(PluginError::InvalidConfiguration);
}
Self::get_rounds_atomic(digest).store(rounds, Ordering::Relaxed);
Ok(())
}
fn pbkdf2_encrypt(cleartext: &str, digest: MessageDigest) -> Result<String, PluginError> {
let rounds = Self::get_pbkdf2_rounds(digest)?;
// The rest of the encryption code
}
dsconf instance plugin pwstorage-scheme pbkdf2-sha512 get-num-iterations
dsconf instance plugin pwstorage-scheme pbkdf2-sha256 set-num-iterations 150000
dsctl instance restart # Changes take effect after restart
The ability to configure PBKDF2 iteration counts enhances the overall security posture of the 389 Directory Server by allowing administrators to scale password hashing complexity in line with evolving computational capabilities.