cryptoki/session/
digesting.rs

1// Copyright 2023 Contributors to the Parsec project.
2// SPDX-License-Identifier: Apache-2.0
3//! Digesting functions
4
5use crate::context::Function;
6use crate::error::{Result, Rv};
7use crate::mechanism::Mechanism;
8use crate::object::ObjectHandle;
9use crate::session::Session;
10use cryptoki_sys::*;
11use std::convert::TryInto;
12
13impl Session {
14    /// Single-part digesting operation
15    pub fn digest(&self, m: &Mechanism, data: &[u8]) -> Result<Vec<u8>> {
16        let mut mechanism: CK_MECHANISM = m.into();
17        let mut digest_len = 0;
18
19        unsafe {
20            Rv::from(get_pkcs11!(self.client(), C_DigestInit)(
21                self.handle(),
22                &mut mechanism as CK_MECHANISM_PTR,
23            ))
24            .into_result(Function::DigestInit)?;
25        }
26
27        // Get the output buffer length
28        unsafe {
29            Rv::from(get_pkcs11!(self.client(), C_Digest)(
30                self.handle(),
31                data.as_ptr() as *mut u8,
32                data.len().try_into()?,
33                std::ptr::null_mut(),
34                &mut digest_len,
35            ))
36            .into_result(Function::Digest)?;
37        }
38
39        let mut digest = vec![0; digest_len.try_into()?];
40
41        unsafe {
42            Rv::from(get_pkcs11!(self.client(), C_Digest)(
43                self.handle(),
44                data.as_ptr() as *mut u8,
45                data.len().try_into()?,
46                digest.as_mut_ptr(),
47                &mut digest_len,
48            ))
49            .into_result(Function::Digest)?;
50        }
51
52        digest.resize(digest_len.try_into()?, 0);
53
54        Ok(digest)
55    }
56
57    /// Starts new multi-part digesting operation
58    pub fn digest_init(&self, m: &Mechanism) -> Result<()> {
59        let mut mechanism: CK_MECHANISM = m.into();
60
61        unsafe {
62            Rv::from(get_pkcs11!(self.client(), C_DigestInit)(
63                self.handle(),
64                &mut mechanism as CK_MECHANISM_PTR,
65            ))
66            .into_result(Function::DigestInit)?;
67        }
68
69        Ok(())
70    }
71
72    /// Continues an ongoing multi-part digesting operation,
73    /// taking in the next part of the data to digest
74    pub fn digest_update(&self, data: &[u8]) -> Result<()> {
75        unsafe {
76            Rv::from(get_pkcs11!(self.client(), C_DigestUpdate)(
77                self.handle(),
78                data.as_ptr() as *mut u8,
79                data.len().try_into()?,
80            ))
81            .into_result(Function::DigestUpdate)?;
82        }
83
84        Ok(())
85    }
86
87    /// Continues an ongoing multi-part digesting operation,
88    /// using the value of a secret key as input
89    pub fn digest_key(&self, key: ObjectHandle) -> Result<()> {
90        unsafe {
91            Rv::from(get_pkcs11!(self.client(), C_DigestKey)(
92                self.handle(),
93                key.handle(),
94            ))
95            .into_result(Function::DigestKey)?;
96        }
97
98        Ok(())
99    }
100
101    /// Finalizes ongoing multi-part digest operation,
102    /// returning the digest
103    pub fn digest_final(&self) -> Result<Vec<u8>> {
104        let mut digest_len = 0;
105
106        // Get the output buffer length
107        unsafe {
108            Rv::from(get_pkcs11!(self.client(), C_DigestFinal)(
109                self.handle(),
110                std::ptr::null_mut(),
111                &mut digest_len,
112            ))
113            .into_result(Function::DigestFinal)?;
114        }
115
116        let mut digest = vec![0; digest_len.try_into()?];
117
118        unsafe {
119            Rv::from(get_pkcs11!(self.client(), C_DigestFinal)(
120                self.handle(),
121                digest.as_mut_ptr(),
122                &mut digest_len,
123            ))
124            .into_result(Function::DigestFinal)?;
125        }
126
127        digest.resize(digest_len.try_into()?, 0);
128
129        Ok(digest)
130    }
131}