192f3ab15Sopenharmony_ci//! Message digest algorithms. 292f3ab15Sopenharmony_ci 392f3ab15Sopenharmony_ci#[cfg(ossl300)] 492f3ab15Sopenharmony_ciuse crate::cvt_p; 592f3ab15Sopenharmony_ci#[cfg(ossl300)] 692f3ab15Sopenharmony_ciuse crate::error::ErrorStack; 792f3ab15Sopenharmony_ci#[cfg(ossl300)] 892f3ab15Sopenharmony_ciuse crate::lib_ctx::LibCtxRef; 992f3ab15Sopenharmony_ciuse crate::nid::Nid; 1092f3ab15Sopenharmony_ciuse cfg_if::cfg_if; 1192f3ab15Sopenharmony_ciuse foreign_types::{ForeignTypeRef, Opaque}; 1292f3ab15Sopenharmony_ciuse openssl_macros::corresponds; 1392f3ab15Sopenharmony_ci#[cfg(ossl300)] 1492f3ab15Sopenharmony_ciuse std::ffi::CString; 1592f3ab15Sopenharmony_ci#[cfg(ossl300)] 1692f3ab15Sopenharmony_ciuse std::ptr; 1792f3ab15Sopenharmony_ci 1892f3ab15Sopenharmony_cicfg_if! { 1992f3ab15Sopenharmony_ci if #[cfg(ossl300)] { 2092f3ab15Sopenharmony_ci use foreign_types::ForeignType; 2192f3ab15Sopenharmony_ci use std::ops::{Deref, DerefMut}; 2292f3ab15Sopenharmony_ci 2392f3ab15Sopenharmony_ci type Inner = *mut ffi::EVP_MD; 2492f3ab15Sopenharmony_ci 2592f3ab15Sopenharmony_ci impl Drop for Md { 2692f3ab15Sopenharmony_ci #[inline] 2792f3ab15Sopenharmony_ci fn drop(&mut self) { 2892f3ab15Sopenharmony_ci unsafe { 2992f3ab15Sopenharmony_ci ffi::EVP_MD_free(self.as_ptr()); 3092f3ab15Sopenharmony_ci } 3192f3ab15Sopenharmony_ci } 3292f3ab15Sopenharmony_ci } 3392f3ab15Sopenharmony_ci 3492f3ab15Sopenharmony_ci impl ForeignType for Md { 3592f3ab15Sopenharmony_ci type CType = ffi::EVP_MD; 3692f3ab15Sopenharmony_ci type Ref = MdRef; 3792f3ab15Sopenharmony_ci 3892f3ab15Sopenharmony_ci #[inline] 3992f3ab15Sopenharmony_ci unsafe fn from_ptr(ptr: *mut Self::CType) -> Self { 4092f3ab15Sopenharmony_ci Md(ptr) 4192f3ab15Sopenharmony_ci } 4292f3ab15Sopenharmony_ci 4392f3ab15Sopenharmony_ci #[inline] 4492f3ab15Sopenharmony_ci fn as_ptr(&self) -> *mut Self::CType { 4592f3ab15Sopenharmony_ci self.0 4692f3ab15Sopenharmony_ci } 4792f3ab15Sopenharmony_ci } 4892f3ab15Sopenharmony_ci 4992f3ab15Sopenharmony_ci impl Deref for Md { 5092f3ab15Sopenharmony_ci type Target = MdRef; 5192f3ab15Sopenharmony_ci 5292f3ab15Sopenharmony_ci #[inline] 5392f3ab15Sopenharmony_ci fn deref(&self) -> &Self::Target { 5492f3ab15Sopenharmony_ci unsafe { 5592f3ab15Sopenharmony_ci MdRef::from_ptr(self.as_ptr()) 5692f3ab15Sopenharmony_ci } 5792f3ab15Sopenharmony_ci } 5892f3ab15Sopenharmony_ci } 5992f3ab15Sopenharmony_ci 6092f3ab15Sopenharmony_ci impl DerefMut for Md { 6192f3ab15Sopenharmony_ci #[inline] 6292f3ab15Sopenharmony_ci fn deref_mut(&mut self) -> &mut Self::Target { 6392f3ab15Sopenharmony_ci unsafe { 6492f3ab15Sopenharmony_ci MdRef::from_ptr_mut(self.as_ptr()) 6592f3ab15Sopenharmony_ci } 6692f3ab15Sopenharmony_ci } 6792f3ab15Sopenharmony_ci } 6892f3ab15Sopenharmony_ci } else { 6992f3ab15Sopenharmony_ci enum Inner {} 7092f3ab15Sopenharmony_ci } 7192f3ab15Sopenharmony_ci} 7292f3ab15Sopenharmony_ci 7392f3ab15Sopenharmony_ci/// A message digest algorithm. 7492f3ab15Sopenharmony_cipub struct Md(Inner); 7592f3ab15Sopenharmony_ci 7692f3ab15Sopenharmony_ciunsafe impl Sync for Md {} 7792f3ab15Sopenharmony_ciunsafe impl Send for Md {} 7892f3ab15Sopenharmony_ci 7992f3ab15Sopenharmony_ciimpl Md { 8092f3ab15Sopenharmony_ci /// Returns the `Md` corresponding to an [`Nid`]. 8192f3ab15Sopenharmony_ci #[corresponds(EVP_get_digestbynid)] 8292f3ab15Sopenharmony_ci pub fn from_nid(type_: Nid) -> Option<&'static MdRef> { 8392f3ab15Sopenharmony_ci unsafe { 8492f3ab15Sopenharmony_ci let ptr = ffi::EVP_get_digestbynid(type_.as_raw()); 8592f3ab15Sopenharmony_ci if ptr.is_null() { 8692f3ab15Sopenharmony_ci None 8792f3ab15Sopenharmony_ci } else { 8892f3ab15Sopenharmony_ci Some(MdRef::from_ptr(ptr as *mut _)) 8992f3ab15Sopenharmony_ci } 9092f3ab15Sopenharmony_ci } 9192f3ab15Sopenharmony_ci } 9292f3ab15Sopenharmony_ci 9392f3ab15Sopenharmony_ci /// Fetches an `Md` object corresponding to the specified algorithm name and properties. 9492f3ab15Sopenharmony_ci /// 9592f3ab15Sopenharmony_ci /// Requires OpenSSL 3.0.0 or newer. 9692f3ab15Sopenharmony_ci #[corresponds(EVP_MD_fetch)] 9792f3ab15Sopenharmony_ci #[cfg(ossl300)] 9892f3ab15Sopenharmony_ci pub fn fetch( 9992f3ab15Sopenharmony_ci ctx: Option<&LibCtxRef>, 10092f3ab15Sopenharmony_ci algorithm: &str, 10192f3ab15Sopenharmony_ci properties: Option<&str>, 10292f3ab15Sopenharmony_ci ) -> Result<Self, ErrorStack> { 10392f3ab15Sopenharmony_ci let algorithm = CString::new(algorithm).unwrap(); 10492f3ab15Sopenharmony_ci let properties = properties.map(|s| CString::new(s).unwrap()); 10592f3ab15Sopenharmony_ci 10692f3ab15Sopenharmony_ci unsafe { 10792f3ab15Sopenharmony_ci let ptr = cvt_p(ffi::EVP_MD_fetch( 10892f3ab15Sopenharmony_ci ctx.map_or(ptr::null_mut(), ForeignTypeRef::as_ptr), 10992f3ab15Sopenharmony_ci algorithm.as_ptr(), 11092f3ab15Sopenharmony_ci properties.map_or(ptr::null_mut(), |s| s.as_ptr()), 11192f3ab15Sopenharmony_ci ))?; 11292f3ab15Sopenharmony_ci 11392f3ab15Sopenharmony_ci Ok(Md::from_ptr(ptr)) 11492f3ab15Sopenharmony_ci } 11592f3ab15Sopenharmony_ci } 11692f3ab15Sopenharmony_ci 11792f3ab15Sopenharmony_ci #[inline] 11892f3ab15Sopenharmony_ci #[cfg(not(boringssl))] 11992f3ab15Sopenharmony_ci pub fn null() -> &'static MdRef { 12092f3ab15Sopenharmony_ci unsafe { MdRef::from_ptr(ffi::EVP_md_null() as *mut _) } 12192f3ab15Sopenharmony_ci } 12292f3ab15Sopenharmony_ci 12392f3ab15Sopenharmony_ci #[inline] 12492f3ab15Sopenharmony_ci pub fn md5() -> &'static MdRef { 12592f3ab15Sopenharmony_ci unsafe { MdRef::from_ptr(ffi::EVP_md5() as *mut _) } 12692f3ab15Sopenharmony_ci } 12792f3ab15Sopenharmony_ci 12892f3ab15Sopenharmony_ci #[inline] 12992f3ab15Sopenharmony_ci pub fn sha1() -> &'static MdRef { 13092f3ab15Sopenharmony_ci unsafe { MdRef::from_ptr(ffi::EVP_sha1() as *mut _) } 13192f3ab15Sopenharmony_ci } 13292f3ab15Sopenharmony_ci 13392f3ab15Sopenharmony_ci #[inline] 13492f3ab15Sopenharmony_ci pub fn sha224() -> &'static MdRef { 13592f3ab15Sopenharmony_ci unsafe { MdRef::from_ptr(ffi::EVP_sha224() as *mut _) } 13692f3ab15Sopenharmony_ci } 13792f3ab15Sopenharmony_ci 13892f3ab15Sopenharmony_ci #[inline] 13992f3ab15Sopenharmony_ci pub fn sha256() -> &'static MdRef { 14092f3ab15Sopenharmony_ci unsafe { MdRef::from_ptr(ffi::EVP_sha256() as *mut _) } 14192f3ab15Sopenharmony_ci } 14292f3ab15Sopenharmony_ci 14392f3ab15Sopenharmony_ci #[inline] 14492f3ab15Sopenharmony_ci pub fn sha384() -> &'static MdRef { 14592f3ab15Sopenharmony_ci unsafe { MdRef::from_ptr(ffi::EVP_sha384() as *mut _) } 14692f3ab15Sopenharmony_ci } 14792f3ab15Sopenharmony_ci 14892f3ab15Sopenharmony_ci #[inline] 14992f3ab15Sopenharmony_ci pub fn sha512() -> &'static MdRef { 15092f3ab15Sopenharmony_ci unsafe { MdRef::from_ptr(ffi::EVP_sha512() as *mut _) } 15192f3ab15Sopenharmony_ci } 15292f3ab15Sopenharmony_ci 15392f3ab15Sopenharmony_ci #[cfg(ossl111)] 15492f3ab15Sopenharmony_ci #[inline] 15592f3ab15Sopenharmony_ci pub fn sha3_224() -> &'static MdRef { 15692f3ab15Sopenharmony_ci unsafe { MdRef::from_ptr(ffi::EVP_sha3_224() as *mut _) } 15792f3ab15Sopenharmony_ci } 15892f3ab15Sopenharmony_ci 15992f3ab15Sopenharmony_ci #[cfg(ossl111)] 16092f3ab15Sopenharmony_ci #[inline] 16192f3ab15Sopenharmony_ci pub fn sha3_256() -> &'static MdRef { 16292f3ab15Sopenharmony_ci unsafe { MdRef::from_ptr(ffi::EVP_sha3_256() as *mut _) } 16392f3ab15Sopenharmony_ci } 16492f3ab15Sopenharmony_ci 16592f3ab15Sopenharmony_ci #[cfg(ossl111)] 16692f3ab15Sopenharmony_ci #[inline] 16792f3ab15Sopenharmony_ci pub fn sha3_384() -> &'static MdRef { 16892f3ab15Sopenharmony_ci unsafe { MdRef::from_ptr(ffi::EVP_sha3_384() as *mut _) } 16992f3ab15Sopenharmony_ci } 17092f3ab15Sopenharmony_ci 17192f3ab15Sopenharmony_ci #[cfg(ossl111)] 17292f3ab15Sopenharmony_ci #[inline] 17392f3ab15Sopenharmony_ci pub fn sha3_512() -> &'static MdRef { 17492f3ab15Sopenharmony_ci unsafe { MdRef::from_ptr(ffi::EVP_sha3_512() as *mut _) } 17592f3ab15Sopenharmony_ci } 17692f3ab15Sopenharmony_ci 17792f3ab15Sopenharmony_ci #[cfg(ossl111)] 17892f3ab15Sopenharmony_ci #[inline] 17992f3ab15Sopenharmony_ci pub fn shake128() -> &'static MdRef { 18092f3ab15Sopenharmony_ci unsafe { MdRef::from_ptr(ffi::EVP_shake128() as *mut _) } 18192f3ab15Sopenharmony_ci } 18292f3ab15Sopenharmony_ci 18392f3ab15Sopenharmony_ci #[cfg(ossl111)] 18492f3ab15Sopenharmony_ci #[inline] 18592f3ab15Sopenharmony_ci pub fn shake256() -> &'static MdRef { 18692f3ab15Sopenharmony_ci unsafe { MdRef::from_ptr(ffi::EVP_shake256() as *mut _) } 18792f3ab15Sopenharmony_ci } 18892f3ab15Sopenharmony_ci 18992f3ab15Sopenharmony_ci #[cfg(not(osslconf = "OPENSSL_NO_RMD160"))] 19092f3ab15Sopenharmony_ci #[inline] 19192f3ab15Sopenharmony_ci #[cfg(not(boringssl))] 19292f3ab15Sopenharmony_ci pub fn ripemd160() -> &'static MdRef { 19392f3ab15Sopenharmony_ci unsafe { MdRef::from_ptr(ffi::EVP_ripemd160() as *mut _) } 19492f3ab15Sopenharmony_ci } 19592f3ab15Sopenharmony_ci 19692f3ab15Sopenharmony_ci #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM3")))] 19792f3ab15Sopenharmony_ci #[inline] 19892f3ab15Sopenharmony_ci #[cfg(not(boringssl))] 19992f3ab15Sopenharmony_ci pub fn sm3() -> &'static MdRef { 20092f3ab15Sopenharmony_ci unsafe { MdRef::from_ptr(ffi::EVP_sm3() as *mut _) } 20192f3ab15Sopenharmony_ci } 20292f3ab15Sopenharmony_ci} 20392f3ab15Sopenharmony_ci 20492f3ab15Sopenharmony_ci/// A reference to an [`Md`]. 20592f3ab15Sopenharmony_cipub struct MdRef(Opaque); 20692f3ab15Sopenharmony_ci 20792f3ab15Sopenharmony_ciimpl ForeignTypeRef for MdRef { 20892f3ab15Sopenharmony_ci type CType = ffi::EVP_MD; 20992f3ab15Sopenharmony_ci} 21092f3ab15Sopenharmony_ci 21192f3ab15Sopenharmony_ciunsafe impl Sync for MdRef {} 21292f3ab15Sopenharmony_ciunsafe impl Send for MdRef {} 21392f3ab15Sopenharmony_ci 21492f3ab15Sopenharmony_ciimpl MdRef { 21592f3ab15Sopenharmony_ci /// Returns the block size of the digest in bytes. 21692f3ab15Sopenharmony_ci #[corresponds(EVP_MD_block_size)] 21792f3ab15Sopenharmony_ci #[inline] 21892f3ab15Sopenharmony_ci pub fn block_size(&self) -> usize { 21992f3ab15Sopenharmony_ci unsafe { ffi::EVP_MD_block_size(self.as_ptr()) as usize } 22092f3ab15Sopenharmony_ci } 22192f3ab15Sopenharmony_ci 22292f3ab15Sopenharmony_ci /// Returns the size of the digest in bytes. 22392f3ab15Sopenharmony_ci #[corresponds(EVP_MD_size)] 22492f3ab15Sopenharmony_ci #[inline] 22592f3ab15Sopenharmony_ci pub fn size(&self) -> usize { 22692f3ab15Sopenharmony_ci unsafe { ffi::EVP_MD_size(self.as_ptr()) as usize } 22792f3ab15Sopenharmony_ci } 22892f3ab15Sopenharmony_ci 22992f3ab15Sopenharmony_ci /// Returns the [`Nid`] of the digest. 23092f3ab15Sopenharmony_ci #[corresponds(EVP_MD_type)] 23192f3ab15Sopenharmony_ci #[inline] 23292f3ab15Sopenharmony_ci pub fn type_(&self) -> Nid { 23392f3ab15Sopenharmony_ci unsafe { Nid::from_raw(ffi::EVP_MD_type(self.as_ptr())) } 23492f3ab15Sopenharmony_ci } 23592f3ab15Sopenharmony_ci} 236