Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add bindings for multi-part operations #252

Merged
merged 13 commits into from
Mar 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 80 additions & 0 deletions cryptoki/src/session/decryption.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,84 @@ impl Session {

Ok(data)
}

/// Starts new multi-part decryption operation
pub fn decrypt_init(&self, mechanism: &Mechanism, key: ObjectHandle) -> Result<()> {
let mut mechanism: CK_MECHANISM = mechanism.into();

unsafe {
Rv::from(get_pkcs11!(self.client(), C_DecryptInit)(
self.handle(),
&mut mechanism as CK_MECHANISM_PTR,
key.handle(),
))
.into_result(Function::DecryptInit)?;
}

Ok(())
}

/// Continues an ongoing multi-part decryption operation,
/// taking in the next part of the encrypted data and returning its decryption
pub fn decrypt_update(&self, encrypted_data: &[u8]) -> Result<Vec<u8>> {
let mut data_len = 0;

// Get the output buffer length
unsafe {
Rv::from(get_pkcs11!(self.client(), C_DecryptUpdate)(
self.handle(),
encrypted_data.as_ptr() as *mut u8,
encrypted_data.len().try_into()?,
std::ptr::null_mut(),
&mut data_len,
))
.into_result(Function::DecryptUpdate)?;
}

let mut data = vec![0; data_len.try_into()?];

unsafe {
Rv::from(get_pkcs11!(self.client(), C_DecryptUpdate)(
self.handle(),
encrypted_data.as_ptr() as *mut u8,
encrypted_data.len().try_into()?,
data.as_mut_ptr(),
&mut data_len,
))
.into_result(Function::DecryptUpdate)?;
}

Ok(data)
}

/// Finalizes ongoing multi-part decryption operation,
/// returning any remaining bytes in the decrypted data
pub fn decrypt_final(&self) -> Result<Vec<u8>> {
let mut data_len = 0;

// Get the output buffer length
unsafe {
Rv::from(get_pkcs11!(self.client(), C_DecryptFinal)(
self.handle(),
std::ptr::null_mut(),
&mut data_len,
))
.into_result(Function::DecryptFinal)?;
}

let mut data = vec![0; data_len.try_into()?];

unsafe {
Rv::from(get_pkcs11!(self.client(), C_DecryptFinal)(
self.handle(),
data.as_mut_ptr(),
&mut data_len,
))
.into_result(Function::DecryptFinal)?;
}

data.resize(data_len.try_into()?, 0);

Ok(data)
}
}
76 changes: 76 additions & 0 deletions cryptoki/src/session/digesting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use crate::context::Function;
use crate::error::{Result, Rv};
use crate::mechanism::Mechanism;
use crate::object::ObjectHandle;
use crate::session::Session;
use cryptoki_sys::*;
use std::convert::TryInto;
Expand Down Expand Up @@ -52,4 +53,79 @@ impl Session {

Ok(digest)
}

/// Starts new multi-part digesting operation
pub fn digest_init(&self, m: &Mechanism) -> Result<()> {
let mut mechanism: CK_MECHANISM = m.into();

unsafe {
Rv::from(get_pkcs11!(self.client(), C_DigestInit)(
self.handle(),
&mut mechanism as CK_MECHANISM_PTR,
))
.into_result(Function::DigestInit)?;
}

Ok(())
}

/// Continues an ongoing multi-part digesting operation,
/// taking in the next part of the data to digest
pub fn digest_update(&self, data: &[u8]) -> Result<()> {
unsafe {
Rv::from(get_pkcs11!(self.client(), C_DigestUpdate)(
self.handle(),
data.as_ptr() as *mut u8,
data.len().try_into()?,
))
.into_result(Function::DigestUpdate)?;
}

Ok(())
}

/// Continues an ongoing multi-part digesting operation,
/// using the value of a secret key as input
pub fn digest_key(&self, key: ObjectHandle) -> Result<()> {
unsafe {
Rv::from(get_pkcs11!(self.client(), C_DigestKey)(
self.handle(),
key.handle(),
))
.into_result(Function::DigestKey)?;
}

Ok(())
}

/// Finalizes ongoing multi-part digest operation,
/// returning the digest
pub fn digest_final(&self) -> Result<Vec<u8>> {
let mut digest_len = 0;

// Get the output buffer length
unsafe {
Rv::from(get_pkcs11!(self.client(), C_DigestFinal)(
self.handle(),
std::ptr::null_mut(),
&mut digest_len,
))
.into_result(Function::DigestFinal)?;
}

let mut digest = vec![0; digest_len.try_into()?];

unsafe {
Rv::from(get_pkcs11!(self.client(), C_DigestFinal)(
self.handle(),
digest.as_mut_ptr(),
&mut digest_len,
))
.into_result(Function::DigestFinal)?;
}

digest.resize(digest_len.try_into()?, 0);

Ok(digest)
}
}
80 changes: 80 additions & 0 deletions cryptoki/src/session/encryption.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,84 @@ impl Session {

Ok(encrypted_data)
}

/// Starts new multi-part encryption operation
pub fn encrypt_init(&self, mechanism: &Mechanism, key: ObjectHandle) -> Result<()> {
let mut mechanism: CK_MECHANISM = mechanism.into();

unsafe {
Rv::from(get_pkcs11!(self.client(), C_EncryptInit)(
self.handle(),
&mut mechanism as CK_MECHANISM_PTR,
key.handle(),
))
.into_result(Function::EncryptInit)?;
}

Ok(())
}

/// Continues an ongoing multi-part encryption operation,
/// taking in the next part of the data and returning its encryption
pub fn encrypt_update(&self, data: &[u8]) -> Result<Vec<u8>> {
let mut encrypted_data_len = 0;

// Get the output buffer length
unsafe {
Rv::from(get_pkcs11!(self.client(), C_EncryptUpdate)(
self.handle(),
data.as_ptr() as *mut u8,
data.len().try_into()?,
std::ptr::null_mut(),
&mut encrypted_data_len,
))
.into_result(Function::EncryptUpdate)?;
}

let mut encrypted_data = vec![0; encrypted_data_len.try_into()?];

unsafe {
Rv::from(get_pkcs11!(self.client(), C_EncryptUpdate)(
self.handle(),
data.as_ptr() as *mut u8,
data.len().try_into()?,
encrypted_data.as_mut_ptr(),
&mut encrypted_data_len,
))
.into_result(Function::EncryptUpdate)?;
}

Ok(encrypted_data)
}

/// Finalizes ongoing multi-part encryption operation,
/// returning any remaining bytes in the encrypted data
pub fn encrypt_final(&self) -> Result<Vec<u8>> {
let mut encrypted_data_len = 0;

// Get the output buffer length
unsafe {
Rv::from(get_pkcs11!(self.client(), C_EncryptFinal)(
self.handle(),
std::ptr::null_mut(),
&mut encrypted_data_len,
))
.into_result(Function::EncryptFinal)?;
}

let mut encrypted_data = vec![0; encrypted_data_len.try_into()?];

unsafe {
Rv::from(get_pkcs11!(self.client(), C_EncryptFinal)(
self.handle(),
encrypted_data.as_mut_ptr(),
&mut encrypted_data_len,
))
.into_result(Function::EncryptFinal)?;
}

encrypted_data.resize(encrypted_data_len.try_into()?, 0);

Ok(encrypted_data)
}
}
108 changes: 108 additions & 0 deletions cryptoki/src/session/signing_macing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,68 @@ impl Session {
Ok(signature)
}

/// Starts new multi-part signing operation
pub fn sign_init(&self, mechanism: &Mechanism, key: ObjectHandle) -> Result<()> {
let mut mechanism: CK_MECHANISM = mechanism.into();

unsafe {
Rv::from(get_pkcs11!(self.client(), C_SignInit)(
self.handle(),
&mut mechanism as CK_MECHANISM_PTR,
key.handle(),
))
.into_result(Function::SignInit)?;
}

Ok(())
}

/// Continues an ongoing multi-part signing operation,
/// taking in the next part of the data to sign
pub fn sign_update(&self, data: &[u8]) -> Result<()> {
unsafe {
Rv::from(get_pkcs11!(self.client(), C_SignUpdate)(
self.handle(),
data.as_ptr() as *mut u8,
data.len().try_into()?,
))
.into_result(Function::SignUpdate)?;
}

Ok(())
}

/// Finalizes ongoing multi-part signing operation,
/// returning the signature
pub fn sign_final(&self) -> Result<Vec<u8>> {
let mut signature_len = 0;

// Get the output buffer length
unsafe {
Rv::from(get_pkcs11!(self.client(), C_SignFinal)(
self.handle(),
std::ptr::null_mut(),
&mut signature_len,
))
.into_result(Function::SignFinal)?;
}

let mut signature = vec![0; signature_len.try_into()?];

unsafe {
Rv::from(get_pkcs11!(self.client(), C_SignFinal)(
self.handle(),
signature.as_mut_ptr(),
&mut signature_len,
))
.into_result(Function::SignFinal)?;
}

signature.resize(signature_len.try_into()?, 0);

Ok(signature)
}

/// Verify data in single-part
pub fn verify(
&self,
Expand Down Expand Up @@ -86,4 +148,50 @@ impl Session {
.into_result(Function::Verify)
}
}

/// Starts new multi-part verifying operation
pub fn verify_init(&self, mechanism: &Mechanism, key: ObjectHandle) -> Result<()> {
let mut mechanism: CK_MECHANISM = mechanism.into();

unsafe {
Rv::from(get_pkcs11!(self.client(), C_VerifyInit)(
self.handle(),
&mut mechanism as CK_MECHANISM_PTR,
key.handle(),
))
.into_result(Function::VerifyInit)?;
}

Ok(())
}

/// Continues an ongoing multi-part verifying operation,
/// taking in the next part of the data to verify
pub fn verify_update(&self, data: &[u8]) -> Result<()> {
unsafe {
Rv::from(get_pkcs11!(self.client(), C_VerifyUpdate)(
self.handle(),
data.as_ptr() as *mut u8,
data.len().try_into()?,
))
.into_result(Function::VerifyUpdate)?;
}

Ok(())
}

/// Finalizes ongoing multi-part verifying operation,
/// returning Ok only if the signature verifies
pub fn verify_final(&self, signature: &[u8]) -> Result<()> {
unsafe {
Rv::from(get_pkcs11!(self.client(), C_VerifyFinal)(
self.handle(),
signature.as_ptr() as *mut u8,
signature.len().try_into()?,
))
.into_result(Function::VerifyFinal)?;
}

Ok(())
}
}
Loading
Loading