// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

//! 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.
//!
//! *This module is available if Mundane is built with the `kdf` feature.*
//!
//! [`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);
                    }
                }
            }
        }
    }
}
