/* Copyright (c) 2023, Google Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

//! 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);
//! ```

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

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

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

/// Used internally to parameterize other primitives.
pub trait Algorithm {
    /// The size of the resulting digest.
    const OUTPUT_LEN: usize;

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

    /// Hashes a message.
    fn hash_to_vec(input: &[u8]) -> 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,
    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,
    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,
    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,
    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,
    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")
        );
    }
}
