// Copyright 2018 Google LLC
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.

//! Key Derivation Functions (KDFs).
//!
//! KDFs are low-level primitives often used to construct higher-level
//! protocols. Unless you're sure that this is what you need, you should
//! probably be using something else. In particular:
//! - If you need password verification, see the [`password`] module.
//!
//! [`password`]: ::password

use std::num::NonZeroU32;

use boringssl;
use hash::Hasher;

/// The PBKDF2 Key Derivation Function.
///
/// `pbkdf2` computes `iter` iterations of PBKDF2 of `password` and `salt`,
/// using an HMAC based on the hash function `H`. It stores the result in
/// `out_key`. Note that PBKDF2 can produce variable-length output, so it will
/// always fill the entirety of `out_key` regardless of its length.
///
/// PBKDF2 is defined in RSA Security LLC's Public Key Cryptography Standards #5
/// (PKCS #5) v2.0. For details, see [RFC 2898 Section 5.2].
///
/// # Security
///
/// While PBKDF2 can produce any amount of key output, the entropy of its output
/// is bounded by the internal state. Be careful that the output key has enough
/// entropy for your needs. See [RFC 2898 Appendix B.1] for a discussion on
/// calculating the effective entropy of PBKDF2. Also remember that new attacks
/// are sometimes discovered, and it is your responsibility to keep up with the
/// latest attacks; RFC 2898's analysis may not be valid forever!
///
/// [RFC 2898 Section 5.2]: https://tools.ietf.org/html/rfc2898#section-5.2
/// [RFC 2898 Appendix B.1]: https://tools.ietf.org/html/rfc2898#appendix-B.1
pub fn pbkdf2<H: Hasher>(password: &[u8], salt: &[u8], iters: NonZeroU32, out_key: &mut [u8]) {
    // PKCS5_PBKDF2_HMAC can only fail on OOM or if iters is 0.
    boringssl::pkcs5_pbkdf2_hmac(password, salt, iters.get(), &H::evp_md(), out_key).unwrap();
}

#[cfg(feature = "insecure")]
pub(crate) mod insecure_pbkdf2_hmac_sha1 {
    use std::num::NonZeroU32;

    #[allow(deprecated)]
    use hash::InsecureSha1;
    use kdf::pbkdf2;

    /// INSECURE: The PBKDF2 Key Derivation Function over HMAC-SHA1.
    ///
    /// # Security
    ///
    /// PBKDF2-HMAC-SHA1 is considered insecure, and should only be used for
    /// compatibility with legacy applications.
    ///
    /// # Behavior
    ///
    /// `pbkdf2_hmac_sha1` computes `iter` iterations of PBKDF2-HMAC-SHA1 of
    /// `password` and `salt`. It stores the result in `out_key`.
    ///
    /// PBKDF2 is defined in RSA Security LLC's Public Key Cryptography
    /// Standards #5 (PKCS #5) v2.0. For details, see [RFC 2898 Section 5.2].
    ///
    /// # Further Security Considerations
    ///
    /// While PBKDF2 can produce any amount of key output, the entropy of its
    /// output is bounded by the internal state. Be careful that the output key
    /// has enough entropy for your needs. See [RFC 2898 Appendix B.1] for a
    /// discussion on calculating the effective entropy of PBKDF2, but keep in
    /// mind that SHA-1's insecurities may affect this analysis! Also remember
    /// that new attacks are sometimes discovered, and it is your responsibility
    /// to keep up with the latest attacks; RFC 2898's analysis may not be valid
    /// forever!
    ///
    /// [RFC 2898 Section 5.2]: https://tools.ietf.org/html/rfc2898#section-5.2
    /// [RFC 2898 Appendix B.1]: https://tools.ietf.org/html/rfc2898#appendix-B.1
    #[deprecated(note = "PBKDF2-HMAC-SHA1 is considered insecure")]
    pub fn insecure_pbkdf2_hmac_sha1(
        password: &[u8],
        salt: &[u8],
        iters: NonZeroU32,
        out_key: &mut [u8],
    ) {
        #[allow(deprecated)]
        pbkdf2::<InsecureSha1>(password, salt, iters, out_key)
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use hash::*;

    #[test]
    fn test_smoke() {
        for password_len in 0..8 {
            for salt_len in 0..8 {
                for iters in 1..8 {
                    for out_key_len in 0..8 {
                        fn test<H: Hasher>(
                            password_len: usize,
                            salt_len: usize,
                            iters: u32,
                            out_key_len: usize,
                        ) {
                            let password = [0, 1, 2, 3, 4, 5, 6, 7];
                            let salt = [0, 1, 2, 3, 4, 5, 6, 7];
                            let mut out_key_0 = [0; 8];
                            let mut out_key_1 = [0; 8];

                            pbkdf2::<H>(
                                &password[..password_len],
                                &salt[..salt_len],
                                NonZeroU32::new(iters).unwrap(),
                                &mut out_key_0[..out_key_len],
                            );
                            pbkdf2::<H>(
                                &password[..password_len],
                                &salt[..salt_len],
                                NonZeroU32::new(iters).unwrap(),
                                &mut out_key_1[..out_key_len],
                            );
                            assert_eq!(&out_key_0[..out_key_len], &out_key_1[..out_key_len]);
                        }

                        test::<Sha256>(password_len, salt_len, iters, out_key_len);
                        test::<Sha384>(password_len, salt_len, iters, out_key_len);
                        test::<Sha512>(password_len, salt_len, iters, out_key_len);
                    }
                }
            }
        }
    }
}
