aws_lc_rs/digest/
digest_ctx.rs1use crate::aws_lc::{
5 EVP_DigestInit_ex, EVP_MD_CTX_cleanup, EVP_MD_CTX_copy, EVP_MD_CTX_init, EVP_MD_CTX,
6};
7use crate::digest::{match_digest_type, Algorithm};
8use crate::error::Unspecified;
9use core::mem::MaybeUninit;
10use core::ptr::null_mut;
11
12pub(crate) struct DigestContext(EVP_MD_CTX);
13
14impl DigestContext {
15 pub fn new(algorithm: &'static Algorithm) -> Result<DigestContext, Unspecified> {
16 let evp_md_type = match_digest_type(&algorithm.id);
17 let mut dc = Self::new_uninit();
18 unsafe {
19 if 1 != EVP_DigestInit_ex(dc.as_mut_ptr(), *evp_md_type, null_mut()) {
20 return Err(Unspecified);
21 }
22 Ok(dc)
23 }
24 }
25
26 pub fn new_uninit() -> DigestContext {
27 let mut dc = MaybeUninit::<EVP_MD_CTX>::uninit();
28 unsafe {
29 EVP_MD_CTX_init(dc.as_mut_ptr());
30 Self(dc.assume_init())
31 }
32 }
33
34 pub(crate) fn as_mut_ptr(&mut self) -> *mut EVP_MD_CTX {
35 &mut self.0
36 }
37
38 pub(crate) fn as_ptr(&self) -> *const EVP_MD_CTX {
39 &self.0
40 }
41}
42
43unsafe impl Send for DigestContext {}
44unsafe impl Sync for DigestContext {}
45
46impl Clone for DigestContext {
47 fn clone(&self) -> Self {
48 self.try_clone().expect("Unable to clone DigestContext")
49 }
50}
51
52impl Drop for DigestContext {
53 fn drop(&mut self) {
54 unsafe {
55 EVP_MD_CTX_cleanup(self.as_mut_ptr());
56 }
57 }
58}
59
60impl DigestContext {
61 fn try_clone(&self) -> Result<Self, &'static str> {
62 let mut dc = MaybeUninit::<EVP_MD_CTX>::uninit();
63 unsafe {
64 if 1 != EVP_MD_CTX_copy(dc.as_mut_ptr(), self.as_ptr()) {
67 return Err("EVP_MD_CTX_copy failed");
68 }
69 Ok(Self(dc.assume_init()))
70 }
71 }
72}