// Copyright 2023 The BoringSSL Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Hash functions.
//!
//! ```
//! use bssl_crypto::digest;
//!
//! // One-shot hashing.
//! let digest: [u8; 32] = digest::Sha256::hash(b"hello");
//!
//! // Incremental hashing.
//! let mut ctx = digest::Sha256::new();
//! ctx.update(b"hel");
//! ctx.update(b"lo");
//! let digest2: [u8; 32] = ctx.digest();
//!
//! assert_eq!(digest, digest2);
//!
//! // Hashing with dynamic dispatch.
//! #[cfg(feature = "std")]
//! {
//!     fn update_hash(ctx: &mut dyn std::io::Write) {
//!         ctx.write(b"hel");
//!         ctx.write(b"lo");
//!     }
//!
//!     let mut ctx = digest::Sha256::new();
//!     update_hash(&mut ctx);
//!     assert_eq!(ctx.digest(), digest);
//! }
//! ```

use crate::{sealed, FfiSlice, ForeignTypeRef};
use alloc::vec::Vec;

#[non_exhaustive]
#[doc(hidden)]
pub struct MdRef;

unsafe impl ForeignTypeRef for MdRef {
    type CType = bssl_sys::EVP_MD;
}

/// Provides the ability to hash in an algorithm-agnostic manner.
pub trait Algorithm {
    /// The size of the resulting digest.
    const OUTPUT_LEN: usize;
    /// The block length (in bytes).
    const BLOCK_LEN: usize;

    /// Gets a reference to a message digest algorithm to be used by the HKDF implementation.
    #[doc(hidden)]
    fn get_md(_: sealed::SealedType) -> &'static MdRef;

    /// Hashes a message.
    fn hash_to_vec(input: &[u8]) -> Vec<u8>;

    /// Create a new context for incremental hashing.
    fn new() -> Self;

    /// Hash the contents of `input`.
    fn update(&mut self, input: &[u8]);

    /// Finish the hashing and return the digest.
    fn digest_to_vec(self) -> Vec<u8>;
}

/// The insecure SHA-1 hash algorithm.
///
/// Some existing protocols depend on SHA-1 and so it is provided here, but it
/// does not provide collision resistance and should not be used if at all
/// avoidable. Use SHA-256 instead.
#[derive(Clone)]
pub struct InsecureSha1 {
    ctx: bssl_sys::SHA_CTX,
}

unsafe_iuf_algo!(
    InsecureSha1,
    20,
    64,
    EVP_sha1,
    SHA1,
    SHA1_Init,
    SHA1_Update,
    SHA1_Final
);

/// The SHA-256 hash algorithm.
#[derive(Clone)]
pub struct Sha256 {
    ctx: bssl_sys::SHA256_CTX,
}

unsafe_iuf_algo!(
    Sha256,
    32,
    64,
    EVP_sha256,
    SHA256,
    SHA256_Init,
    SHA256_Update,
    SHA256_Final
);

/// The SHA-384 hash algorithm.
#[derive(Clone)]
pub struct Sha384 {
    ctx: bssl_sys::SHA512_CTX,
}

unsafe_iuf_algo!(
    Sha384,
    48,
    128,
    EVP_sha384,
    SHA384,
    SHA384_Init,
    SHA384_Update,
    SHA384_Final
);

/// The SHA-512 hash algorithm.
#[derive(Clone)]
pub struct Sha512 {
    ctx: bssl_sys::SHA512_CTX,
}

unsafe_iuf_algo!(
    Sha512,
    64,
    128,
    EVP_sha512,
    SHA512,
    SHA512_Init,
    SHA512_Update,
    SHA512_Final
);

/// The SHA-512/256 hash algorithm.
#[derive(Clone)]
pub struct Sha512_256 {
    ctx: bssl_sys::SHA512_CTX,
}

unsafe_iuf_algo!(
    Sha512_256,
    32,
    128,
    EVP_sha512_256,
    SHA512_256,
    SHA512_256_Init,
    SHA512_256_Update,
    SHA512_256_Final
);

#[cfg(test)]
mod test {
    use super::*;
    use crate::test_helpers::decode_hex;

    #[test]
    fn sha256_c_type() {
        unsafe {
            assert_eq!(
                MdRef::from_ptr(bssl_sys::EVP_sha256() as *mut _).as_ptr(),
                bssl_sys::EVP_sha256() as *mut _
            )
        }
    }

    #[test]
    fn sha512_c_type() {
        unsafe {
            assert_eq!(
                MdRef::from_ptr(bssl_sys::EVP_sha512() as *mut _).as_ptr(),
                bssl_sys::EVP_sha512() as *mut _
            )
        }
    }

    #[test]
    fn sha1() {
        assert_eq!(
            decode_hex("a9993e364706816aba3e25717850c26c9cd0d89d"),
            InsecureSha1::hash(b"abc")
        );
    }

    #[test]
    fn sha256() {
        let msg: [u8; 4] = decode_hex("74ba2521");
        let expected_digest: [u8; 32] =
            decode_hex("b16aa56be3880d18cd41e68384cf1ec8c17680c45a02b1575dc1518923ae8b0e");

        assert_eq!(Sha256::hash(&msg), expected_digest);

        let mut ctx = Sha256::new();
        ctx.update(&msg);
        assert_eq!(expected_digest, ctx.digest());

        let mut ctx = Sha256::new();
        ctx.update(&msg[0..1]);
        let mut ctx2 = ctx.clone();
        ctx2.update(&msg[1..]);
        assert_eq!(expected_digest, ctx2.digest());
    }

    #[test]
    fn sha384() {
        assert_eq!(
            decode_hex("cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7"),
            Sha384::hash(b"abc")
        );
    }

    #[test]
    fn sha512() {
        let msg: [u8; 4] = decode_hex("23be86d5");
        let expected_digest: [u8; 64] = decode_hex(concat!(
            "76d42c8eadea35a69990c63a762f330614a4699977f058adb988f406fb0be8f2",
            "ea3dce3a2bbd1d827b70b9b299ae6f9e5058ee97b50bd4922d6d37ddc761f8eb"
        ));

        assert_eq!(Sha512::hash(&msg), expected_digest);

        let mut ctx = Sha512::new();
        ctx.update(&msg);
        assert_eq!(expected_digest, ctx.digest());
    }

    #[test]
    fn sha512_256() {
        assert_eq!(
            decode_hex("53048e2681941ef99b2e29b76b4c7dabe4c2d0c634fc6d46e0e2f13107e7af23"),
            Sha512_256::hash(b"abc")
        );
    }
}
