192f3ab15Sopenharmony_ci//! Message digest (hash) computation support. 292f3ab15Sopenharmony_ci//! 392f3ab15Sopenharmony_ci//! # Examples 492f3ab15Sopenharmony_ci//! 592f3ab15Sopenharmony_ci//! Calculate a hash in one go: 692f3ab15Sopenharmony_ci//! 792f3ab15Sopenharmony_ci//! ``` 892f3ab15Sopenharmony_ci//! # fn main() -> Result<(), Box<dyn std::error::Error>> { 992f3ab15Sopenharmony_ci//! use openssl::hash::{hash, MessageDigest}; 1092f3ab15Sopenharmony_ci//! 1192f3ab15Sopenharmony_ci//! let data = b"\x42\xF4\x97\xE0"; 1292f3ab15Sopenharmony_ci//! let spec = b"\x7c\x43\x0f\x17\x8a\xef\xdf\x14\x87\xfe\xe7\x14\x4e\x96\x41\xe2"; 1392f3ab15Sopenharmony_ci//! let res = hash(MessageDigest::md5(), data)?; 1492f3ab15Sopenharmony_ci//! assert_eq!(&*res, spec); 1592f3ab15Sopenharmony_ci//! # Ok(()) } 1692f3ab15Sopenharmony_ci//! ``` 1792f3ab15Sopenharmony_ci//! 1892f3ab15Sopenharmony_ci//! Supply the input in chunks: 1992f3ab15Sopenharmony_ci//! 2092f3ab15Sopenharmony_ci//! ``` 2192f3ab15Sopenharmony_ci//! use openssl::hash::{Hasher, MessageDigest}; 2292f3ab15Sopenharmony_ci//! 2392f3ab15Sopenharmony_ci//! # fn main() -> Result<(), Box<dyn std::error::Error>> { 2492f3ab15Sopenharmony_ci//! let mut hasher = Hasher::new(MessageDigest::sha256())?; 2592f3ab15Sopenharmony_ci//! hasher.update(b"test")?; 2692f3ab15Sopenharmony_ci//! hasher.update(b"this")?; 2792f3ab15Sopenharmony_ci//! let digest: &[u8] = &hasher.finish()?; 2892f3ab15Sopenharmony_ci//! 2992f3ab15Sopenharmony_ci//! let expected = hex::decode("9740e652ab5b4acd997a7cca13d6696702ccb2d441cca59fc6e285127f28cfe6")?; 3092f3ab15Sopenharmony_ci//! assert_eq!(digest, expected); 3192f3ab15Sopenharmony_ci//! # Ok(()) } 3292f3ab15Sopenharmony_ci//! ``` 3392f3ab15Sopenharmony_ciuse cfg_if::cfg_if; 3492f3ab15Sopenharmony_ciuse std::ffi::CString; 3592f3ab15Sopenharmony_ciuse std::fmt; 3692f3ab15Sopenharmony_ciuse std::io; 3792f3ab15Sopenharmony_ciuse std::io::prelude::*; 3892f3ab15Sopenharmony_ciuse std::ops::{Deref, DerefMut}; 3992f3ab15Sopenharmony_ciuse std::ptr; 4092f3ab15Sopenharmony_ci 4192f3ab15Sopenharmony_ciuse crate::error::ErrorStack; 4292f3ab15Sopenharmony_ciuse crate::nid::Nid; 4392f3ab15Sopenharmony_ciuse crate::{cvt, cvt_p}; 4492f3ab15Sopenharmony_ci 4592f3ab15Sopenharmony_cicfg_if! { 4692f3ab15Sopenharmony_ci if #[cfg(any(ossl110, boringssl))] { 4792f3ab15Sopenharmony_ci use ffi::{EVP_MD_CTX_free, EVP_MD_CTX_new}; 4892f3ab15Sopenharmony_ci } else { 4992f3ab15Sopenharmony_ci use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free}; 5092f3ab15Sopenharmony_ci } 5192f3ab15Sopenharmony_ci} 5292f3ab15Sopenharmony_ci 5392f3ab15Sopenharmony_ci/// A message digest algorithm. 5492f3ab15Sopenharmony_ci#[derive(Copy, Clone, PartialEq, Eq)] 5592f3ab15Sopenharmony_cipub struct MessageDigest(*const ffi::EVP_MD); 5692f3ab15Sopenharmony_ci 5792f3ab15Sopenharmony_ciimpl MessageDigest { 5892f3ab15Sopenharmony_ci /// Creates a `MessageDigest` from a raw OpenSSL pointer. 5992f3ab15Sopenharmony_ci /// 6092f3ab15Sopenharmony_ci /// # Safety 6192f3ab15Sopenharmony_ci /// 6292f3ab15Sopenharmony_ci /// The caller must ensure the pointer is valid. 6392f3ab15Sopenharmony_ci pub unsafe fn from_ptr(x: *const ffi::EVP_MD) -> Self { 6492f3ab15Sopenharmony_ci MessageDigest(x) 6592f3ab15Sopenharmony_ci } 6692f3ab15Sopenharmony_ci 6792f3ab15Sopenharmony_ci /// Returns the `MessageDigest` corresponding to an `Nid`. 6892f3ab15Sopenharmony_ci /// 6992f3ab15Sopenharmony_ci /// This corresponds to [`EVP_get_digestbynid`]. 7092f3ab15Sopenharmony_ci /// 7192f3ab15Sopenharmony_ci /// [`EVP_get_digestbynid`]: https://www.openssl.org/docs/manmaster/crypto/EVP_DigestInit.html 7292f3ab15Sopenharmony_ci pub fn from_nid(type_: Nid) -> Option<MessageDigest> { 7392f3ab15Sopenharmony_ci unsafe { 7492f3ab15Sopenharmony_ci let ptr = ffi::EVP_get_digestbynid(type_.as_raw()); 7592f3ab15Sopenharmony_ci if ptr.is_null() { 7692f3ab15Sopenharmony_ci None 7792f3ab15Sopenharmony_ci } else { 7892f3ab15Sopenharmony_ci Some(MessageDigest(ptr)) 7992f3ab15Sopenharmony_ci } 8092f3ab15Sopenharmony_ci } 8192f3ab15Sopenharmony_ci } 8292f3ab15Sopenharmony_ci 8392f3ab15Sopenharmony_ci /// Returns the `MessageDigest` corresponding to an algorithm name. 8492f3ab15Sopenharmony_ci /// 8592f3ab15Sopenharmony_ci /// This corresponds to [`EVP_get_digestbyname`]. 8692f3ab15Sopenharmony_ci /// 8792f3ab15Sopenharmony_ci /// [`EVP_get_digestbyname`]: https://www.openssl.org/docs/manmaster/crypto/EVP_DigestInit.html 8892f3ab15Sopenharmony_ci pub fn from_name(name: &str) -> Option<MessageDigest> { 8992f3ab15Sopenharmony_ci ffi::init(); 9092f3ab15Sopenharmony_ci let name = CString::new(name).ok()?; 9192f3ab15Sopenharmony_ci unsafe { 9292f3ab15Sopenharmony_ci let ptr = ffi::EVP_get_digestbyname(name.as_ptr()); 9392f3ab15Sopenharmony_ci if ptr.is_null() { 9492f3ab15Sopenharmony_ci None 9592f3ab15Sopenharmony_ci } else { 9692f3ab15Sopenharmony_ci Some(MessageDigest(ptr)) 9792f3ab15Sopenharmony_ci } 9892f3ab15Sopenharmony_ci } 9992f3ab15Sopenharmony_ci } 10092f3ab15Sopenharmony_ci 10192f3ab15Sopenharmony_ci #[cfg(not(boringssl))] 10292f3ab15Sopenharmony_ci pub fn null() -> MessageDigest { 10392f3ab15Sopenharmony_ci unsafe { MessageDigest(ffi::EVP_md_null()) } 10492f3ab15Sopenharmony_ci } 10592f3ab15Sopenharmony_ci 10692f3ab15Sopenharmony_ci pub fn md5() -> MessageDigest { 10792f3ab15Sopenharmony_ci unsafe { MessageDigest(ffi::EVP_md5()) } 10892f3ab15Sopenharmony_ci } 10992f3ab15Sopenharmony_ci 11092f3ab15Sopenharmony_ci pub fn sha1() -> MessageDigest { 11192f3ab15Sopenharmony_ci unsafe { MessageDigest(ffi::EVP_sha1()) } 11292f3ab15Sopenharmony_ci } 11392f3ab15Sopenharmony_ci 11492f3ab15Sopenharmony_ci pub fn sha224() -> MessageDigest { 11592f3ab15Sopenharmony_ci unsafe { MessageDigest(ffi::EVP_sha224()) } 11692f3ab15Sopenharmony_ci } 11792f3ab15Sopenharmony_ci 11892f3ab15Sopenharmony_ci pub fn sha256() -> MessageDigest { 11992f3ab15Sopenharmony_ci unsafe { MessageDigest(ffi::EVP_sha256()) } 12092f3ab15Sopenharmony_ci } 12192f3ab15Sopenharmony_ci 12292f3ab15Sopenharmony_ci pub fn sha384() -> MessageDigest { 12392f3ab15Sopenharmony_ci unsafe { MessageDigest(ffi::EVP_sha384()) } 12492f3ab15Sopenharmony_ci } 12592f3ab15Sopenharmony_ci 12692f3ab15Sopenharmony_ci pub fn sha512() -> MessageDigest { 12792f3ab15Sopenharmony_ci unsafe { MessageDigest(ffi::EVP_sha512()) } 12892f3ab15Sopenharmony_ci } 12992f3ab15Sopenharmony_ci 13092f3ab15Sopenharmony_ci #[cfg(ossl111)] 13192f3ab15Sopenharmony_ci pub fn sha3_224() -> MessageDigest { 13292f3ab15Sopenharmony_ci unsafe { MessageDigest(ffi::EVP_sha3_224()) } 13392f3ab15Sopenharmony_ci } 13492f3ab15Sopenharmony_ci 13592f3ab15Sopenharmony_ci #[cfg(ossl111)] 13692f3ab15Sopenharmony_ci pub fn sha3_256() -> MessageDigest { 13792f3ab15Sopenharmony_ci unsafe { MessageDigest(ffi::EVP_sha3_256()) } 13892f3ab15Sopenharmony_ci } 13992f3ab15Sopenharmony_ci 14092f3ab15Sopenharmony_ci #[cfg(ossl111)] 14192f3ab15Sopenharmony_ci pub fn sha3_384() -> MessageDigest { 14292f3ab15Sopenharmony_ci unsafe { MessageDigest(ffi::EVP_sha3_384()) } 14392f3ab15Sopenharmony_ci } 14492f3ab15Sopenharmony_ci 14592f3ab15Sopenharmony_ci #[cfg(ossl111)] 14692f3ab15Sopenharmony_ci pub fn sha3_512() -> MessageDigest { 14792f3ab15Sopenharmony_ci unsafe { MessageDigest(ffi::EVP_sha3_512()) } 14892f3ab15Sopenharmony_ci } 14992f3ab15Sopenharmony_ci 15092f3ab15Sopenharmony_ci #[cfg(ossl111)] 15192f3ab15Sopenharmony_ci pub fn shake_128() -> MessageDigest { 15292f3ab15Sopenharmony_ci unsafe { MessageDigest(ffi::EVP_shake128()) } 15392f3ab15Sopenharmony_ci } 15492f3ab15Sopenharmony_ci 15592f3ab15Sopenharmony_ci #[cfg(ossl111)] 15692f3ab15Sopenharmony_ci pub fn shake_256() -> MessageDigest { 15792f3ab15Sopenharmony_ci unsafe { MessageDigest(ffi::EVP_shake256()) } 15892f3ab15Sopenharmony_ci } 15992f3ab15Sopenharmony_ci 16092f3ab15Sopenharmony_ci #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_RMD160")))] 16192f3ab15Sopenharmony_ci pub fn ripemd160() -> MessageDigest { 16292f3ab15Sopenharmony_ci unsafe { MessageDigest(ffi::EVP_ripemd160()) } 16392f3ab15Sopenharmony_ci } 16492f3ab15Sopenharmony_ci 16592f3ab15Sopenharmony_ci #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM3")))] 16692f3ab15Sopenharmony_ci pub fn sm3() -> MessageDigest { 16792f3ab15Sopenharmony_ci unsafe { MessageDigest(ffi::EVP_sm3()) } 16892f3ab15Sopenharmony_ci } 16992f3ab15Sopenharmony_ci 17092f3ab15Sopenharmony_ci #[allow(clippy::trivially_copy_pass_by_ref)] 17192f3ab15Sopenharmony_ci pub fn as_ptr(&self) -> *const ffi::EVP_MD { 17292f3ab15Sopenharmony_ci self.0 17392f3ab15Sopenharmony_ci } 17492f3ab15Sopenharmony_ci 17592f3ab15Sopenharmony_ci /// The block size of the digest in bytes. 17692f3ab15Sopenharmony_ci #[allow(clippy::trivially_copy_pass_by_ref)] 17792f3ab15Sopenharmony_ci pub fn block_size(&self) -> usize { 17892f3ab15Sopenharmony_ci unsafe { ffi::EVP_MD_block_size(self.0) as usize } 17992f3ab15Sopenharmony_ci } 18092f3ab15Sopenharmony_ci 18192f3ab15Sopenharmony_ci /// The size of the digest in bytes. 18292f3ab15Sopenharmony_ci #[allow(clippy::trivially_copy_pass_by_ref)] 18392f3ab15Sopenharmony_ci pub fn size(&self) -> usize { 18492f3ab15Sopenharmony_ci unsafe { ffi::EVP_MD_size(self.0) as usize } 18592f3ab15Sopenharmony_ci } 18692f3ab15Sopenharmony_ci 18792f3ab15Sopenharmony_ci /// The name of the digest. 18892f3ab15Sopenharmony_ci #[allow(clippy::trivially_copy_pass_by_ref)] 18992f3ab15Sopenharmony_ci pub fn type_(&self) -> Nid { 19092f3ab15Sopenharmony_ci Nid::from_raw(unsafe { ffi::EVP_MD_type(self.0) }) 19192f3ab15Sopenharmony_ci } 19292f3ab15Sopenharmony_ci} 19392f3ab15Sopenharmony_ci 19492f3ab15Sopenharmony_ciunsafe impl Sync for MessageDigest {} 19592f3ab15Sopenharmony_ciunsafe impl Send for MessageDigest {} 19692f3ab15Sopenharmony_ci 19792f3ab15Sopenharmony_ci#[derive(PartialEq, Copy, Clone)] 19892f3ab15Sopenharmony_cienum State { 19992f3ab15Sopenharmony_ci Reset, 20092f3ab15Sopenharmony_ci Updated, 20192f3ab15Sopenharmony_ci Finalized, 20292f3ab15Sopenharmony_ci} 20392f3ab15Sopenharmony_ci 20492f3ab15Sopenharmony_ciuse self::State::*; 20592f3ab15Sopenharmony_ci 20692f3ab15Sopenharmony_ci/// Provides message digest (hash) computation. 20792f3ab15Sopenharmony_ci/// 20892f3ab15Sopenharmony_ci/// # Examples 20992f3ab15Sopenharmony_ci/// 21092f3ab15Sopenharmony_ci/// ``` 21192f3ab15Sopenharmony_ci/// use openssl::hash::{Hasher, MessageDigest}; 21292f3ab15Sopenharmony_ci/// 21392f3ab15Sopenharmony_ci/// # fn main() -> Result<(), Box<dyn std::error::Error>> { 21492f3ab15Sopenharmony_ci/// let data = [b"\x42\xF4", b"\x97\xE0"]; 21592f3ab15Sopenharmony_ci/// let spec = b"\x7c\x43\x0f\x17\x8a\xef\xdf\x14\x87\xfe\xe7\x14\x4e\x96\x41\xe2"; 21692f3ab15Sopenharmony_ci/// let mut h = Hasher::new(MessageDigest::md5())?; 21792f3ab15Sopenharmony_ci/// h.update(data[0])?; 21892f3ab15Sopenharmony_ci/// h.update(data[1])?; 21992f3ab15Sopenharmony_ci/// let res = h.finish()?; 22092f3ab15Sopenharmony_ci/// assert_eq!(&*res, spec); 22192f3ab15Sopenharmony_ci/// # Ok(()) } 22292f3ab15Sopenharmony_ci/// ``` 22392f3ab15Sopenharmony_ci/// 22492f3ab15Sopenharmony_ci/// # Warning 22592f3ab15Sopenharmony_ci/// 22692f3ab15Sopenharmony_ci/// Don't actually use MD5 and SHA-1 hashes, they're not secure anymore. 22792f3ab15Sopenharmony_ci/// 22892f3ab15Sopenharmony_ci/// Don't ever hash passwords, use the functions in the `pkcs5` module or bcrypt/scrypt instead. 22992f3ab15Sopenharmony_ci/// 23092f3ab15Sopenharmony_ci/// For extendable output functions (XOFs, i.e. SHAKE128/SHAKE256), 23192f3ab15Sopenharmony_ci/// you must use [`Hasher::finish_xof`] instead of [`Hasher::finish`] 23292f3ab15Sopenharmony_ci/// and provide a `buf` to store the hash. The hash will be as long as 23392f3ab15Sopenharmony_ci/// the `buf`. 23492f3ab15Sopenharmony_cipub struct Hasher { 23592f3ab15Sopenharmony_ci ctx: *mut ffi::EVP_MD_CTX, 23692f3ab15Sopenharmony_ci md: *const ffi::EVP_MD, 23792f3ab15Sopenharmony_ci type_: MessageDigest, 23892f3ab15Sopenharmony_ci state: State, 23992f3ab15Sopenharmony_ci} 24092f3ab15Sopenharmony_ci 24192f3ab15Sopenharmony_ciunsafe impl Sync for Hasher {} 24292f3ab15Sopenharmony_ciunsafe impl Send for Hasher {} 24392f3ab15Sopenharmony_ci 24492f3ab15Sopenharmony_ciimpl Hasher { 24592f3ab15Sopenharmony_ci /// Creates a new `Hasher` with the specified hash type. 24692f3ab15Sopenharmony_ci pub fn new(ty: MessageDigest) -> Result<Hasher, ErrorStack> { 24792f3ab15Sopenharmony_ci ffi::init(); 24892f3ab15Sopenharmony_ci 24992f3ab15Sopenharmony_ci let ctx = unsafe { cvt_p(EVP_MD_CTX_new())? }; 25092f3ab15Sopenharmony_ci 25192f3ab15Sopenharmony_ci let mut h = Hasher { 25292f3ab15Sopenharmony_ci ctx, 25392f3ab15Sopenharmony_ci md: ty.as_ptr(), 25492f3ab15Sopenharmony_ci type_: ty, 25592f3ab15Sopenharmony_ci state: Finalized, 25692f3ab15Sopenharmony_ci }; 25792f3ab15Sopenharmony_ci h.init()?; 25892f3ab15Sopenharmony_ci Ok(h) 25992f3ab15Sopenharmony_ci } 26092f3ab15Sopenharmony_ci 26192f3ab15Sopenharmony_ci fn init(&mut self) -> Result<(), ErrorStack> { 26292f3ab15Sopenharmony_ci match self.state { 26392f3ab15Sopenharmony_ci Reset => return Ok(()), 26492f3ab15Sopenharmony_ci Updated => { 26592f3ab15Sopenharmony_ci self.finish()?; 26692f3ab15Sopenharmony_ci } 26792f3ab15Sopenharmony_ci Finalized => (), 26892f3ab15Sopenharmony_ci } 26992f3ab15Sopenharmony_ci unsafe { 27092f3ab15Sopenharmony_ci cvt(ffi::EVP_DigestInit_ex(self.ctx, self.md, ptr::null_mut()))?; 27192f3ab15Sopenharmony_ci } 27292f3ab15Sopenharmony_ci self.state = Reset; 27392f3ab15Sopenharmony_ci Ok(()) 27492f3ab15Sopenharmony_ci } 27592f3ab15Sopenharmony_ci 27692f3ab15Sopenharmony_ci /// Feeds data into the hasher. 27792f3ab15Sopenharmony_ci pub fn update(&mut self, data: &[u8]) -> Result<(), ErrorStack> { 27892f3ab15Sopenharmony_ci if self.state == Finalized { 27992f3ab15Sopenharmony_ci self.init()?; 28092f3ab15Sopenharmony_ci } 28192f3ab15Sopenharmony_ci unsafe { 28292f3ab15Sopenharmony_ci cvt(ffi::EVP_DigestUpdate( 28392f3ab15Sopenharmony_ci self.ctx, 28492f3ab15Sopenharmony_ci data.as_ptr() as *mut _, 28592f3ab15Sopenharmony_ci data.len(), 28692f3ab15Sopenharmony_ci ))?; 28792f3ab15Sopenharmony_ci } 28892f3ab15Sopenharmony_ci self.state = Updated; 28992f3ab15Sopenharmony_ci Ok(()) 29092f3ab15Sopenharmony_ci } 29192f3ab15Sopenharmony_ci 29292f3ab15Sopenharmony_ci /// Returns the hash of the data written and resets the non-XOF hasher. 29392f3ab15Sopenharmony_ci pub fn finish(&mut self) -> Result<DigestBytes, ErrorStack> { 29492f3ab15Sopenharmony_ci if self.state == Finalized { 29592f3ab15Sopenharmony_ci self.init()?; 29692f3ab15Sopenharmony_ci } 29792f3ab15Sopenharmony_ci unsafe { 29892f3ab15Sopenharmony_ci #[cfg(not(boringssl))] 29992f3ab15Sopenharmony_ci let mut len = ffi::EVP_MAX_MD_SIZE; 30092f3ab15Sopenharmony_ci #[cfg(boringssl)] 30192f3ab15Sopenharmony_ci let mut len = ffi::EVP_MAX_MD_SIZE as u32; 30292f3ab15Sopenharmony_ci let mut buf = [0; ffi::EVP_MAX_MD_SIZE as usize]; 30392f3ab15Sopenharmony_ci cvt(ffi::EVP_DigestFinal_ex( 30492f3ab15Sopenharmony_ci self.ctx, 30592f3ab15Sopenharmony_ci buf.as_mut_ptr(), 30692f3ab15Sopenharmony_ci &mut len, 30792f3ab15Sopenharmony_ci ))?; 30892f3ab15Sopenharmony_ci self.state = Finalized; 30992f3ab15Sopenharmony_ci Ok(DigestBytes { 31092f3ab15Sopenharmony_ci buf, 31192f3ab15Sopenharmony_ci len: len as usize, 31292f3ab15Sopenharmony_ci }) 31392f3ab15Sopenharmony_ci } 31492f3ab15Sopenharmony_ci } 31592f3ab15Sopenharmony_ci 31692f3ab15Sopenharmony_ci /// Writes the hash of the data into the supplied buf and resets the XOF hasher. 31792f3ab15Sopenharmony_ci /// The hash will be as long as the buf. 31892f3ab15Sopenharmony_ci #[cfg(ossl111)] 31992f3ab15Sopenharmony_ci pub fn finish_xof(&mut self, buf: &mut [u8]) -> Result<(), ErrorStack> { 32092f3ab15Sopenharmony_ci if self.state == Finalized { 32192f3ab15Sopenharmony_ci self.init()?; 32292f3ab15Sopenharmony_ci } 32392f3ab15Sopenharmony_ci unsafe { 32492f3ab15Sopenharmony_ci cvt(ffi::EVP_DigestFinalXOF( 32592f3ab15Sopenharmony_ci self.ctx, 32692f3ab15Sopenharmony_ci buf.as_mut_ptr(), 32792f3ab15Sopenharmony_ci buf.len(), 32892f3ab15Sopenharmony_ci ))?; 32992f3ab15Sopenharmony_ci self.state = Finalized; 33092f3ab15Sopenharmony_ci Ok(()) 33192f3ab15Sopenharmony_ci } 33292f3ab15Sopenharmony_ci } 33392f3ab15Sopenharmony_ci} 33492f3ab15Sopenharmony_ci 33592f3ab15Sopenharmony_ciimpl Write for Hasher { 33692f3ab15Sopenharmony_ci #[inline] 33792f3ab15Sopenharmony_ci fn write(&mut self, buf: &[u8]) -> io::Result<usize> { 33892f3ab15Sopenharmony_ci self.update(buf)?; 33992f3ab15Sopenharmony_ci Ok(buf.len()) 34092f3ab15Sopenharmony_ci } 34192f3ab15Sopenharmony_ci 34292f3ab15Sopenharmony_ci fn flush(&mut self) -> io::Result<()> { 34392f3ab15Sopenharmony_ci Ok(()) 34492f3ab15Sopenharmony_ci } 34592f3ab15Sopenharmony_ci} 34692f3ab15Sopenharmony_ci 34792f3ab15Sopenharmony_ciimpl Clone for Hasher { 34892f3ab15Sopenharmony_ci fn clone(&self) -> Hasher { 34992f3ab15Sopenharmony_ci let ctx = unsafe { 35092f3ab15Sopenharmony_ci let ctx = EVP_MD_CTX_new(); 35192f3ab15Sopenharmony_ci assert!(!ctx.is_null()); 35292f3ab15Sopenharmony_ci let r = ffi::EVP_MD_CTX_copy_ex(ctx, self.ctx); 35392f3ab15Sopenharmony_ci assert_eq!(r, 1); 35492f3ab15Sopenharmony_ci ctx 35592f3ab15Sopenharmony_ci }; 35692f3ab15Sopenharmony_ci Hasher { 35792f3ab15Sopenharmony_ci ctx, 35892f3ab15Sopenharmony_ci md: self.md, 35992f3ab15Sopenharmony_ci type_: self.type_, 36092f3ab15Sopenharmony_ci state: self.state, 36192f3ab15Sopenharmony_ci } 36292f3ab15Sopenharmony_ci } 36392f3ab15Sopenharmony_ci} 36492f3ab15Sopenharmony_ci 36592f3ab15Sopenharmony_ciimpl Drop for Hasher { 36692f3ab15Sopenharmony_ci fn drop(&mut self) { 36792f3ab15Sopenharmony_ci unsafe { 36892f3ab15Sopenharmony_ci if self.state != Finalized { 36992f3ab15Sopenharmony_ci drop(self.finish()); 37092f3ab15Sopenharmony_ci } 37192f3ab15Sopenharmony_ci EVP_MD_CTX_free(self.ctx); 37292f3ab15Sopenharmony_ci } 37392f3ab15Sopenharmony_ci } 37492f3ab15Sopenharmony_ci} 37592f3ab15Sopenharmony_ci 37692f3ab15Sopenharmony_ci/// The resulting bytes of a digest. 37792f3ab15Sopenharmony_ci/// 37892f3ab15Sopenharmony_ci/// This type derefs to a byte slice - it exists to avoid allocating memory to 37992f3ab15Sopenharmony_ci/// store the digest data. 38092f3ab15Sopenharmony_ci#[derive(Copy)] 38192f3ab15Sopenharmony_cipub struct DigestBytes { 38292f3ab15Sopenharmony_ci pub(crate) buf: [u8; ffi::EVP_MAX_MD_SIZE as usize], 38392f3ab15Sopenharmony_ci pub(crate) len: usize, 38492f3ab15Sopenharmony_ci} 38592f3ab15Sopenharmony_ci 38692f3ab15Sopenharmony_ciimpl Clone for DigestBytes { 38792f3ab15Sopenharmony_ci #[inline] 38892f3ab15Sopenharmony_ci fn clone(&self) -> DigestBytes { 38992f3ab15Sopenharmony_ci *self 39092f3ab15Sopenharmony_ci } 39192f3ab15Sopenharmony_ci} 39292f3ab15Sopenharmony_ci 39392f3ab15Sopenharmony_ciimpl Deref for DigestBytes { 39492f3ab15Sopenharmony_ci type Target = [u8]; 39592f3ab15Sopenharmony_ci 39692f3ab15Sopenharmony_ci #[inline] 39792f3ab15Sopenharmony_ci fn deref(&self) -> &[u8] { 39892f3ab15Sopenharmony_ci &self.buf[..self.len] 39992f3ab15Sopenharmony_ci } 40092f3ab15Sopenharmony_ci} 40192f3ab15Sopenharmony_ci 40292f3ab15Sopenharmony_ciimpl DerefMut for DigestBytes { 40392f3ab15Sopenharmony_ci #[inline] 40492f3ab15Sopenharmony_ci fn deref_mut(&mut self) -> &mut [u8] { 40592f3ab15Sopenharmony_ci &mut self.buf[..self.len] 40692f3ab15Sopenharmony_ci } 40792f3ab15Sopenharmony_ci} 40892f3ab15Sopenharmony_ci 40992f3ab15Sopenharmony_ciimpl AsRef<[u8]> for DigestBytes { 41092f3ab15Sopenharmony_ci #[inline] 41192f3ab15Sopenharmony_ci fn as_ref(&self) -> &[u8] { 41292f3ab15Sopenharmony_ci self.deref() 41392f3ab15Sopenharmony_ci } 41492f3ab15Sopenharmony_ci} 41592f3ab15Sopenharmony_ci 41692f3ab15Sopenharmony_ciimpl fmt::Debug for DigestBytes { 41792f3ab15Sopenharmony_ci fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { 41892f3ab15Sopenharmony_ci fmt::Debug::fmt(&**self, fmt) 41992f3ab15Sopenharmony_ci } 42092f3ab15Sopenharmony_ci} 42192f3ab15Sopenharmony_ci 42292f3ab15Sopenharmony_ci/// Computes the hash of the `data` with the non-XOF hasher `t`. 42392f3ab15Sopenharmony_ci/// 42492f3ab15Sopenharmony_ci/// # Examples 42592f3ab15Sopenharmony_ci/// 42692f3ab15Sopenharmony_ci/// ``` 42792f3ab15Sopenharmony_ci/// # fn main() -> Result<(), Box<dyn std::error::Error>> { 42892f3ab15Sopenharmony_ci/// use openssl::hash::{hash, MessageDigest}; 42992f3ab15Sopenharmony_ci/// 43092f3ab15Sopenharmony_ci/// let data = b"\x42\xF4\x97\xE0"; 43192f3ab15Sopenharmony_ci/// let spec = b"\x7c\x43\x0f\x17\x8a\xef\xdf\x14\x87\xfe\xe7\x14\x4e\x96\x41\xe2"; 43292f3ab15Sopenharmony_ci/// let res = hash(MessageDigest::md5(), data)?; 43392f3ab15Sopenharmony_ci/// assert_eq!(&*res, spec); 43492f3ab15Sopenharmony_ci/// # Ok(()) } 43592f3ab15Sopenharmony_ci/// ``` 43692f3ab15Sopenharmony_cipub fn hash(t: MessageDigest, data: &[u8]) -> Result<DigestBytes, ErrorStack> { 43792f3ab15Sopenharmony_ci let mut h = Hasher::new(t)?; 43892f3ab15Sopenharmony_ci h.update(data)?; 43992f3ab15Sopenharmony_ci h.finish() 44092f3ab15Sopenharmony_ci} 44192f3ab15Sopenharmony_ci 44292f3ab15Sopenharmony_ci/// Computes the hash of the `data` with the XOF hasher `t` and stores it in `buf`. 44392f3ab15Sopenharmony_ci/// 44492f3ab15Sopenharmony_ci/// # Examples 44592f3ab15Sopenharmony_ci/// 44692f3ab15Sopenharmony_ci/// ``` 44792f3ab15Sopenharmony_ci/// use openssl::hash::{hash_xof, MessageDigest}; 44892f3ab15Sopenharmony_ci/// 44992f3ab15Sopenharmony_ci/// let data = b"\x41\x6c\x6c\x20\x79\x6f\x75\x72\x20\x62\x61\x73\x65\x20\x61\x72\x65\x20\x62\x65\x6c\x6f\x6e\x67\x20\x74\x6f\x20\x75\x73"; 45092f3ab15Sopenharmony_ci/// let spec = b"\x49\xd0\x69\x7f\xf5\x08\x11\x1d\x8b\x84\xf1\x5e\x46\xda\xf1\x35"; 45192f3ab15Sopenharmony_ci/// let mut buf = vec![0; 16]; 45292f3ab15Sopenharmony_ci/// hash_xof(MessageDigest::shake_128(), data, buf.as_mut_slice()).unwrap(); 45392f3ab15Sopenharmony_ci/// assert_eq!(buf, spec); 45492f3ab15Sopenharmony_ci/// ``` 45592f3ab15Sopenharmony_ci/// 45692f3ab15Sopenharmony_ci#[cfg(ossl111)] 45792f3ab15Sopenharmony_cipub fn hash_xof(t: MessageDigest, data: &[u8], buf: &mut [u8]) -> Result<(), ErrorStack> { 45892f3ab15Sopenharmony_ci let mut h = Hasher::new(t)?; 45992f3ab15Sopenharmony_ci h.update(data)?; 46092f3ab15Sopenharmony_ci h.finish_xof(buf) 46192f3ab15Sopenharmony_ci} 46292f3ab15Sopenharmony_ci 46392f3ab15Sopenharmony_ci#[cfg(test)] 46492f3ab15Sopenharmony_cimod tests { 46592f3ab15Sopenharmony_ci use hex::{self, FromHex}; 46692f3ab15Sopenharmony_ci use std::io::prelude::*; 46792f3ab15Sopenharmony_ci 46892f3ab15Sopenharmony_ci use super::*; 46992f3ab15Sopenharmony_ci 47092f3ab15Sopenharmony_ci fn hash_test(hashtype: MessageDigest, hashtest: &(&str, &str)) { 47192f3ab15Sopenharmony_ci let res = hash(hashtype, &Vec::from_hex(hashtest.0).unwrap()).unwrap(); 47292f3ab15Sopenharmony_ci assert_eq!(hex::encode(res), hashtest.1); 47392f3ab15Sopenharmony_ci } 47492f3ab15Sopenharmony_ci 47592f3ab15Sopenharmony_ci #[cfg(ossl111)] 47692f3ab15Sopenharmony_ci fn hash_xof_test(hashtype: MessageDigest, hashtest: &(&str, &str)) { 47792f3ab15Sopenharmony_ci let expected = Vec::from_hex(hashtest.1).unwrap(); 47892f3ab15Sopenharmony_ci let mut buf = vec![0; expected.len()]; 47992f3ab15Sopenharmony_ci hash_xof( 48092f3ab15Sopenharmony_ci hashtype, 48192f3ab15Sopenharmony_ci &Vec::from_hex(hashtest.0).unwrap(), 48292f3ab15Sopenharmony_ci buf.as_mut_slice(), 48392f3ab15Sopenharmony_ci ) 48492f3ab15Sopenharmony_ci .unwrap(); 48592f3ab15Sopenharmony_ci assert_eq!(buf, expected); 48692f3ab15Sopenharmony_ci } 48792f3ab15Sopenharmony_ci 48892f3ab15Sopenharmony_ci fn hash_recycle_test(h: &mut Hasher, hashtest: &(&str, &str)) { 48992f3ab15Sopenharmony_ci h.write_all(&Vec::from_hex(hashtest.0).unwrap()).unwrap(); 49092f3ab15Sopenharmony_ci let res = h.finish().unwrap(); 49192f3ab15Sopenharmony_ci assert_eq!(hex::encode(res), hashtest.1); 49292f3ab15Sopenharmony_ci } 49392f3ab15Sopenharmony_ci 49492f3ab15Sopenharmony_ci // Test vectors from http://www.nsrl.nist.gov/testdata/ 49592f3ab15Sopenharmony_ci const MD5_TESTS: [(&str, &str); 13] = [ 49692f3ab15Sopenharmony_ci ("", "d41d8cd98f00b204e9800998ecf8427e"), 49792f3ab15Sopenharmony_ci ("7F", "83acb6e67e50e31db6ed341dd2de1595"), 49892f3ab15Sopenharmony_ci ("EC9C", "0b07f0d4ca797d8ac58874f887cb0b68"), 49992f3ab15Sopenharmony_ci ("FEE57A", "e0d583171eb06d56198fc0ef22173907"), 50092f3ab15Sopenharmony_ci ("42F497E0", "7c430f178aefdf1487fee7144e9641e2"), 50192f3ab15Sopenharmony_ci ("C53B777F1C", "75ef141d64cb37ec423da2d9d440c925"), 50292f3ab15Sopenharmony_ci ("89D5B576327B", "ebbaf15eb0ed784c6faa9dc32831bf33"), 50392f3ab15Sopenharmony_ci ("5D4CCE781EB190", "ce175c4b08172019f05e6b5279889f2c"), 50492f3ab15Sopenharmony_ci ("81901FE94932D7B9", "cd4d2f62b8cdb3a0cf968a735a239281"), 50592f3ab15Sopenharmony_ci ("C9FFDEE7788EFB4EC9", "e0841a231ab698db30c6c0f3f246c014"), 50692f3ab15Sopenharmony_ci ("66AC4B7EBA95E53DC10B", "a3b3cea71910d9af56742aa0bb2fe329"), 50792f3ab15Sopenharmony_ci ("A510CD18F7A56852EB0319", "577e216843dd11573574d3fb209b97d8"), 50892f3ab15Sopenharmony_ci ( 50992f3ab15Sopenharmony_ci "AAED18DBE8938C19ED734A8D", 51092f3ab15Sopenharmony_ci "6f80fb775f27e0a4ce5c2f42fc72c5f1", 51192f3ab15Sopenharmony_ci ), 51292f3ab15Sopenharmony_ci ]; 51392f3ab15Sopenharmony_ci 51492f3ab15Sopenharmony_ci #[test] 51592f3ab15Sopenharmony_ci fn test_md5() { 51692f3ab15Sopenharmony_ci for test in MD5_TESTS.iter() { 51792f3ab15Sopenharmony_ci hash_test(MessageDigest::md5(), test); 51892f3ab15Sopenharmony_ci } 51992f3ab15Sopenharmony_ci 52092f3ab15Sopenharmony_ci assert_eq!(MessageDigest::md5().block_size(), 64); 52192f3ab15Sopenharmony_ci assert_eq!(MessageDigest::md5().size(), 16); 52292f3ab15Sopenharmony_ci assert_eq!(MessageDigest::md5().type_().as_raw(), Nid::MD5.as_raw()); 52392f3ab15Sopenharmony_ci } 52492f3ab15Sopenharmony_ci 52592f3ab15Sopenharmony_ci #[test] 52692f3ab15Sopenharmony_ci fn test_md5_recycle() { 52792f3ab15Sopenharmony_ci let mut h = Hasher::new(MessageDigest::md5()).unwrap(); 52892f3ab15Sopenharmony_ci for test in MD5_TESTS.iter() { 52992f3ab15Sopenharmony_ci hash_recycle_test(&mut h, test); 53092f3ab15Sopenharmony_ci } 53192f3ab15Sopenharmony_ci } 53292f3ab15Sopenharmony_ci 53392f3ab15Sopenharmony_ci #[test] 53492f3ab15Sopenharmony_ci fn test_finish_twice() { 53592f3ab15Sopenharmony_ci let mut h = Hasher::new(MessageDigest::md5()).unwrap(); 53692f3ab15Sopenharmony_ci h.write_all(&Vec::from_hex(MD5_TESTS[6].0).unwrap()) 53792f3ab15Sopenharmony_ci .unwrap(); 53892f3ab15Sopenharmony_ci h.finish().unwrap(); 53992f3ab15Sopenharmony_ci let res = h.finish().unwrap(); 54092f3ab15Sopenharmony_ci let null = hash(MessageDigest::md5(), &[]).unwrap(); 54192f3ab15Sopenharmony_ci assert_eq!(&*res, &*null); 54292f3ab15Sopenharmony_ci } 54392f3ab15Sopenharmony_ci 54492f3ab15Sopenharmony_ci #[test] 54592f3ab15Sopenharmony_ci #[allow(clippy::redundant_clone)] 54692f3ab15Sopenharmony_ci fn test_clone() { 54792f3ab15Sopenharmony_ci let i = 7; 54892f3ab15Sopenharmony_ci let inp = Vec::from_hex(MD5_TESTS[i].0).unwrap(); 54992f3ab15Sopenharmony_ci assert!(inp.len() > 2); 55092f3ab15Sopenharmony_ci let p = inp.len() / 2; 55192f3ab15Sopenharmony_ci let h0 = Hasher::new(MessageDigest::md5()).unwrap(); 55292f3ab15Sopenharmony_ci 55392f3ab15Sopenharmony_ci println!("Clone a new hasher"); 55492f3ab15Sopenharmony_ci let mut h1 = h0.clone(); 55592f3ab15Sopenharmony_ci h1.write_all(&inp[..p]).unwrap(); 55692f3ab15Sopenharmony_ci { 55792f3ab15Sopenharmony_ci println!("Clone an updated hasher"); 55892f3ab15Sopenharmony_ci let mut h2 = h1.clone(); 55992f3ab15Sopenharmony_ci h2.write_all(&inp[p..]).unwrap(); 56092f3ab15Sopenharmony_ci let res = h2.finish().unwrap(); 56192f3ab15Sopenharmony_ci assert_eq!(hex::encode(res), MD5_TESTS[i].1); 56292f3ab15Sopenharmony_ci } 56392f3ab15Sopenharmony_ci h1.write_all(&inp[p..]).unwrap(); 56492f3ab15Sopenharmony_ci let res = h1.finish().unwrap(); 56592f3ab15Sopenharmony_ci assert_eq!(hex::encode(res), MD5_TESTS[i].1); 56692f3ab15Sopenharmony_ci 56792f3ab15Sopenharmony_ci println!("Clone a finished hasher"); 56892f3ab15Sopenharmony_ci let mut h3 = h1.clone(); 56992f3ab15Sopenharmony_ci h3.write_all(&Vec::from_hex(MD5_TESTS[i + 1].0).unwrap()) 57092f3ab15Sopenharmony_ci .unwrap(); 57192f3ab15Sopenharmony_ci let res = h3.finish().unwrap(); 57292f3ab15Sopenharmony_ci assert_eq!(hex::encode(res), MD5_TESTS[i + 1].1); 57392f3ab15Sopenharmony_ci } 57492f3ab15Sopenharmony_ci 57592f3ab15Sopenharmony_ci #[test] 57692f3ab15Sopenharmony_ci fn test_sha1() { 57792f3ab15Sopenharmony_ci let tests = [("616263", "a9993e364706816aba3e25717850c26c9cd0d89d")]; 57892f3ab15Sopenharmony_ci 57992f3ab15Sopenharmony_ci for test in tests.iter() { 58092f3ab15Sopenharmony_ci hash_test(MessageDigest::sha1(), test); 58192f3ab15Sopenharmony_ci } 58292f3ab15Sopenharmony_ci 58392f3ab15Sopenharmony_ci assert_eq!(MessageDigest::sha1().block_size(), 64); 58492f3ab15Sopenharmony_ci assert_eq!(MessageDigest::sha1().size(), 20); 58592f3ab15Sopenharmony_ci assert_eq!(MessageDigest::sha1().type_().as_raw(), Nid::SHA1.as_raw()); 58692f3ab15Sopenharmony_ci } 58792f3ab15Sopenharmony_ci 58892f3ab15Sopenharmony_ci #[test] 58992f3ab15Sopenharmony_ci fn test_sha256() { 59092f3ab15Sopenharmony_ci let tests = [( 59192f3ab15Sopenharmony_ci "616263", 59292f3ab15Sopenharmony_ci "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", 59392f3ab15Sopenharmony_ci )]; 59492f3ab15Sopenharmony_ci 59592f3ab15Sopenharmony_ci for test in tests.iter() { 59692f3ab15Sopenharmony_ci hash_test(MessageDigest::sha256(), test); 59792f3ab15Sopenharmony_ci } 59892f3ab15Sopenharmony_ci 59992f3ab15Sopenharmony_ci assert_eq!(MessageDigest::sha256().block_size(), 64); 60092f3ab15Sopenharmony_ci assert_eq!(MessageDigest::sha256().size(), 32); 60192f3ab15Sopenharmony_ci assert_eq!( 60292f3ab15Sopenharmony_ci MessageDigest::sha256().type_().as_raw(), 60392f3ab15Sopenharmony_ci Nid::SHA256.as_raw() 60492f3ab15Sopenharmony_ci ); 60592f3ab15Sopenharmony_ci } 60692f3ab15Sopenharmony_ci 60792f3ab15Sopenharmony_ci #[test] 60892f3ab15Sopenharmony_ci fn test_sha512() { 60992f3ab15Sopenharmony_ci let tests = [( 61092f3ab15Sopenharmony_ci "737465766566696e647365766572797468696e67", 61192f3ab15Sopenharmony_ci "ba61d1f1af0f2dd80729f6cc900f19c0966bd38ba5c75e4471ef11b771dfe7551afab7fcbd300fdc4418f2\ 61292f3ab15Sopenharmony_ci b07a028fcd99e7b6446a566f2d9bcd7c604a1ea801", 61392f3ab15Sopenharmony_ci )]; 61492f3ab15Sopenharmony_ci 61592f3ab15Sopenharmony_ci for test in tests.iter() { 61692f3ab15Sopenharmony_ci hash_test(MessageDigest::sha512(), test); 61792f3ab15Sopenharmony_ci } 61892f3ab15Sopenharmony_ci 61992f3ab15Sopenharmony_ci assert_eq!(MessageDigest::sha512().block_size(), 128); 62092f3ab15Sopenharmony_ci assert_eq!(MessageDigest::sha512().size(), 64); 62192f3ab15Sopenharmony_ci assert_eq!( 62292f3ab15Sopenharmony_ci MessageDigest::sha512().type_().as_raw(), 62392f3ab15Sopenharmony_ci Nid::SHA512.as_raw() 62492f3ab15Sopenharmony_ci ); 62592f3ab15Sopenharmony_ci } 62692f3ab15Sopenharmony_ci 62792f3ab15Sopenharmony_ci #[cfg(ossl111)] 62892f3ab15Sopenharmony_ci #[test] 62992f3ab15Sopenharmony_ci fn test_sha3_224() { 63092f3ab15Sopenharmony_ci let tests = [( 63192f3ab15Sopenharmony_ci "416c6c20796f75722062617365206172652062656c6f6e6720746f207573", 63292f3ab15Sopenharmony_ci "1de092dd9fbcbbf450f26264f4778abd48af851f2832924554c56913", 63392f3ab15Sopenharmony_ci )]; 63492f3ab15Sopenharmony_ci 63592f3ab15Sopenharmony_ci for test in tests.iter() { 63692f3ab15Sopenharmony_ci hash_test(MessageDigest::sha3_224(), test); 63792f3ab15Sopenharmony_ci } 63892f3ab15Sopenharmony_ci 63992f3ab15Sopenharmony_ci assert_eq!(MessageDigest::sha3_224().block_size(), 144); 64092f3ab15Sopenharmony_ci assert_eq!(MessageDigest::sha3_224().size(), 28); 64192f3ab15Sopenharmony_ci assert_eq!( 64292f3ab15Sopenharmony_ci MessageDigest::sha3_224().type_().as_raw(), 64392f3ab15Sopenharmony_ci Nid::SHA3_224.as_raw() 64492f3ab15Sopenharmony_ci ); 64592f3ab15Sopenharmony_ci } 64692f3ab15Sopenharmony_ci 64792f3ab15Sopenharmony_ci #[cfg(ossl111)] 64892f3ab15Sopenharmony_ci #[test] 64992f3ab15Sopenharmony_ci fn test_sha3_256() { 65092f3ab15Sopenharmony_ci let tests = [( 65192f3ab15Sopenharmony_ci "416c6c20796f75722062617365206172652062656c6f6e6720746f207573", 65292f3ab15Sopenharmony_ci "b38e38f08bc1c0091ed4b5f060fe13e86aa4179578513ad11a6e3abba0062f61", 65392f3ab15Sopenharmony_ci )]; 65492f3ab15Sopenharmony_ci 65592f3ab15Sopenharmony_ci for test in tests.iter() { 65692f3ab15Sopenharmony_ci hash_test(MessageDigest::sha3_256(), test); 65792f3ab15Sopenharmony_ci } 65892f3ab15Sopenharmony_ci 65992f3ab15Sopenharmony_ci assert_eq!(MessageDigest::sha3_256().block_size(), 136); 66092f3ab15Sopenharmony_ci assert_eq!(MessageDigest::sha3_256().size(), 32); 66192f3ab15Sopenharmony_ci assert_eq!( 66292f3ab15Sopenharmony_ci MessageDigest::sha3_256().type_().as_raw(), 66392f3ab15Sopenharmony_ci Nid::SHA3_256.as_raw() 66492f3ab15Sopenharmony_ci ); 66592f3ab15Sopenharmony_ci } 66692f3ab15Sopenharmony_ci 66792f3ab15Sopenharmony_ci #[cfg(ossl111)] 66892f3ab15Sopenharmony_ci #[test] 66992f3ab15Sopenharmony_ci fn test_sha3_384() { 67092f3ab15Sopenharmony_ci let tests = [("416c6c20796f75722062617365206172652062656c6f6e6720746f207573", 67192f3ab15Sopenharmony_ci "966ee786ab3482dd811bf7c8fa8db79aa1f52f6c3c369942ef14240ebd857c6ff626ec35d9e131ff64d328\ 67292f3ab15Sopenharmony_ci ef2008ff16" 67392f3ab15Sopenharmony_ci )]; 67492f3ab15Sopenharmony_ci 67592f3ab15Sopenharmony_ci for test in tests.iter() { 67692f3ab15Sopenharmony_ci hash_test(MessageDigest::sha3_384(), test); 67792f3ab15Sopenharmony_ci } 67892f3ab15Sopenharmony_ci 67992f3ab15Sopenharmony_ci assert_eq!(MessageDigest::sha3_384().block_size(), 104); 68092f3ab15Sopenharmony_ci assert_eq!(MessageDigest::sha3_384().size(), 48); 68192f3ab15Sopenharmony_ci assert_eq!( 68292f3ab15Sopenharmony_ci MessageDigest::sha3_384().type_().as_raw(), 68392f3ab15Sopenharmony_ci Nid::SHA3_384.as_raw() 68492f3ab15Sopenharmony_ci ); 68592f3ab15Sopenharmony_ci } 68692f3ab15Sopenharmony_ci 68792f3ab15Sopenharmony_ci #[cfg(ossl111)] 68892f3ab15Sopenharmony_ci #[test] 68992f3ab15Sopenharmony_ci fn test_sha3_512() { 69092f3ab15Sopenharmony_ci let tests = [("416c6c20796f75722062617365206172652062656c6f6e6720746f207573", 69192f3ab15Sopenharmony_ci "c072288ef728cd53a029c47687960b9225893532f42b923156e37020bdc1eda753aafbf30af859d4f4c3a1\ 69292f3ab15Sopenharmony_ci 807caee3a79f8eb02dcd61589fbbdf5f40c8787a72" 69392f3ab15Sopenharmony_ci )]; 69492f3ab15Sopenharmony_ci 69592f3ab15Sopenharmony_ci for test in tests.iter() { 69692f3ab15Sopenharmony_ci hash_test(MessageDigest::sha3_512(), test); 69792f3ab15Sopenharmony_ci } 69892f3ab15Sopenharmony_ci 69992f3ab15Sopenharmony_ci assert_eq!(MessageDigest::sha3_512().block_size(), 72); 70092f3ab15Sopenharmony_ci assert_eq!(MessageDigest::sha3_512().size(), 64); 70192f3ab15Sopenharmony_ci assert_eq!( 70292f3ab15Sopenharmony_ci MessageDigest::sha3_512().type_().as_raw(), 70392f3ab15Sopenharmony_ci Nid::SHA3_512.as_raw() 70492f3ab15Sopenharmony_ci ); 70592f3ab15Sopenharmony_ci } 70692f3ab15Sopenharmony_ci 70792f3ab15Sopenharmony_ci #[cfg(ossl111)] 70892f3ab15Sopenharmony_ci #[test] 70992f3ab15Sopenharmony_ci fn test_shake_128() { 71092f3ab15Sopenharmony_ci let tests = [( 71192f3ab15Sopenharmony_ci "416c6c20796f75722062617365206172652062656c6f6e6720746f207573", 71292f3ab15Sopenharmony_ci "49d0697ff508111d8b84f15e46daf135", 71392f3ab15Sopenharmony_ci )]; 71492f3ab15Sopenharmony_ci 71592f3ab15Sopenharmony_ci for test in tests.iter() { 71692f3ab15Sopenharmony_ci hash_xof_test(MessageDigest::shake_128(), test); 71792f3ab15Sopenharmony_ci } 71892f3ab15Sopenharmony_ci 71992f3ab15Sopenharmony_ci assert_eq!(MessageDigest::shake_128().block_size(), 168); 72092f3ab15Sopenharmony_ci assert_eq!(MessageDigest::shake_128().size(), 16); 72192f3ab15Sopenharmony_ci assert_eq!( 72292f3ab15Sopenharmony_ci MessageDigest::shake_128().type_().as_raw(), 72392f3ab15Sopenharmony_ci Nid::SHAKE128.as_raw() 72492f3ab15Sopenharmony_ci ); 72592f3ab15Sopenharmony_ci } 72692f3ab15Sopenharmony_ci 72792f3ab15Sopenharmony_ci #[cfg(ossl111)] 72892f3ab15Sopenharmony_ci #[test] 72992f3ab15Sopenharmony_ci fn test_shake_256() { 73092f3ab15Sopenharmony_ci let tests = [( 73192f3ab15Sopenharmony_ci "416c6c20796f75722062617365206172652062656c6f6e6720746f207573", 73292f3ab15Sopenharmony_ci "4e2dfdaa75d1e049d0eaeffe28e76b17cea47b650fb8826fe48b94664326a697", 73392f3ab15Sopenharmony_ci )]; 73492f3ab15Sopenharmony_ci 73592f3ab15Sopenharmony_ci for test in tests.iter() { 73692f3ab15Sopenharmony_ci hash_xof_test(MessageDigest::shake_256(), test); 73792f3ab15Sopenharmony_ci } 73892f3ab15Sopenharmony_ci 73992f3ab15Sopenharmony_ci assert_eq!(MessageDigest::shake_256().block_size(), 136); 74092f3ab15Sopenharmony_ci assert_eq!(MessageDigest::shake_256().size(), 32); 74192f3ab15Sopenharmony_ci assert_eq!( 74292f3ab15Sopenharmony_ci MessageDigest::shake_256().type_().as_raw(), 74392f3ab15Sopenharmony_ci Nid::SHAKE256.as_raw() 74492f3ab15Sopenharmony_ci ); 74592f3ab15Sopenharmony_ci } 74692f3ab15Sopenharmony_ci 74792f3ab15Sopenharmony_ci #[test] 74892f3ab15Sopenharmony_ci #[cfg(not(boringssl))] 74992f3ab15Sopenharmony_ci #[cfg_attr(ossl300, ignore)] 75092f3ab15Sopenharmony_ci fn test_ripemd160() { 75192f3ab15Sopenharmony_ci #[cfg(ossl300)] 75292f3ab15Sopenharmony_ci let _provider = crate::provider::Provider::try_load(None, "legacy", true).unwrap(); 75392f3ab15Sopenharmony_ci 75492f3ab15Sopenharmony_ci let tests = [("616263", "8eb208f7e05d987a9b044a8e98c6b087f15a0bfc")]; 75592f3ab15Sopenharmony_ci 75692f3ab15Sopenharmony_ci for test in tests.iter() { 75792f3ab15Sopenharmony_ci hash_test(MessageDigest::ripemd160(), test); 75892f3ab15Sopenharmony_ci } 75992f3ab15Sopenharmony_ci 76092f3ab15Sopenharmony_ci assert_eq!(MessageDigest::ripemd160().block_size(), 64); 76192f3ab15Sopenharmony_ci assert_eq!(MessageDigest::ripemd160().size(), 20); 76292f3ab15Sopenharmony_ci assert_eq!( 76392f3ab15Sopenharmony_ci MessageDigest::ripemd160().type_().as_raw(), 76492f3ab15Sopenharmony_ci Nid::RIPEMD160.as_raw() 76592f3ab15Sopenharmony_ci ); 76692f3ab15Sopenharmony_ci } 76792f3ab15Sopenharmony_ci 76892f3ab15Sopenharmony_ci #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM3")))] 76992f3ab15Sopenharmony_ci #[test] 77092f3ab15Sopenharmony_ci fn test_sm3() { 77192f3ab15Sopenharmony_ci let tests = [( 77292f3ab15Sopenharmony_ci "616263", 77392f3ab15Sopenharmony_ci "66c7f0f462eeedd9d1f2d46bdc10e4e24167c4875cf2f7a2297da02b8f4ba8e0", 77492f3ab15Sopenharmony_ci )]; 77592f3ab15Sopenharmony_ci 77692f3ab15Sopenharmony_ci for test in tests.iter() { 77792f3ab15Sopenharmony_ci hash_test(MessageDigest::sm3(), test); 77892f3ab15Sopenharmony_ci } 77992f3ab15Sopenharmony_ci 78092f3ab15Sopenharmony_ci assert_eq!(MessageDigest::sm3().block_size(), 64); 78192f3ab15Sopenharmony_ci assert_eq!(MessageDigest::sm3().size(), 32); 78292f3ab15Sopenharmony_ci assert_eq!(MessageDigest::sm3().type_().as_raw(), Nid::SM3.as_raw()); 78392f3ab15Sopenharmony_ci } 78492f3ab15Sopenharmony_ci 78592f3ab15Sopenharmony_ci #[test] 78692f3ab15Sopenharmony_ci fn from_nid() { 78792f3ab15Sopenharmony_ci assert_eq!( 78892f3ab15Sopenharmony_ci MessageDigest::from_nid(Nid::SHA256).unwrap().as_ptr(), 78992f3ab15Sopenharmony_ci MessageDigest::sha256().as_ptr() 79092f3ab15Sopenharmony_ci ); 79192f3ab15Sopenharmony_ci } 79292f3ab15Sopenharmony_ci 79392f3ab15Sopenharmony_ci #[test] 79492f3ab15Sopenharmony_ci fn from_name() { 79592f3ab15Sopenharmony_ci assert_eq!( 79692f3ab15Sopenharmony_ci MessageDigest::from_name("SHA256").unwrap().as_ptr(), 79792f3ab15Sopenharmony_ci MessageDigest::sha256().as_ptr() 79892f3ab15Sopenharmony_ci ) 79992f3ab15Sopenharmony_ci } 80092f3ab15Sopenharmony_ci} 801