use crate::error::Result;
use crate::fns::digest::internal_digest_update;
use crate::fns::encryption::{
internal_decrypt_update, internal_encrypt_update,
};
use crate::fns::log_debug;
use crate::fns::signing::{internal_sign_update, internal_verify_update};
use crate::mechanism::{Decryption, Digest, Encryption, Sign, Verify};
use crate::pkcs11::*;
use crate::STATE;
#[inline(always)]
fn digest_encrypt_update(
s_handle: CK_SESSION_HANDLE,
part: CK_BYTE_PTR,
part_len: CK_ULONG,
encrypted_part: CK_BYTE_PTR,
pul_encrypted_part_len: CK_ULONG_PTR,
) -> Result<()> {
let rstate = STATE.rlock()?;
let mut session = rstate.get_session_mut(s_handle)?;
let res = session
.check_op::<dyn Digest>()
.and_then(|_| session.check_op::<dyn Encryption>())
.and_then(|_| {
internal_encrypt_update(
&mut session,
part,
part_len,
encrypted_part,
pul_encrypted_part_len,
)
});
if let Err(e) = res {
if e.kind() != crate::error::ErrorKind::BufferTooSmall {
let _ = session.cancel_operation::<dyn Digest>();
let _ = session.cancel_operation::<dyn Encryption>();
}
return Err(e);
}
if encrypted_part.is_null() {
return Ok(());
}
if let Err(e) = internal_digest_update(&mut session, part, part_len) {
let _ = session.cancel_operation::<dyn Encryption>();
return Err(e);
}
Ok(())
}
pub extern "C" fn fn_digest_encrypt_update(
s_handle: CK_SESSION_HANDLE,
part: CK_BYTE_PTR,
part_len: CK_ULONG,
encrypted_part: CK_BYTE_PTR,
pul_encrypted_part_len: CK_ULONG_PTR,
) -> CK_RV {
log_debug!(
"C_DigestEncryptUpdate: s_handle={} part={:?} part_len={} encrypted_part={:?} pul_encrypted_part_len={:?}",
s_handle,
part,
part_len,
encrypted_part,
pul_encrypted_part_len
);
let rv = match digest_encrypt_update(
s_handle,
part,
part_len,
encrypted_part,
pul_encrypted_part_len,
) {
Ok(()) => CKR_OK,
Err(e) => e.rv(),
};
log_debug!("C_DigestEncryptUpdate: ret={}", rv);
rv
}
#[inline(always)]
fn decrypt_digest_update(
s_handle: CK_SESSION_HANDLE,
encrypted_part: CK_BYTE_PTR,
encrypted_part_len: CK_ULONG,
part: CK_BYTE_PTR,
pul_part_len: CK_ULONG_PTR,
) -> Result<()> {
let rstate = STATE.rlock()?;
let mut session = rstate.get_session_mut(s_handle)?;
let res = session
.check_op::<dyn Digest>()
.and_then(|_| session.check_op::<dyn Decryption>())
.and_then(|_| {
internal_decrypt_update(
&mut session,
encrypted_part,
encrypted_part_len,
part,
pul_part_len,
)
});
if let Err(e) = res {
if e.kind() != crate::error::ErrorKind::BufferTooSmall {
let _ = session.cancel_operation::<dyn Digest>();
let _ = session.cancel_operation::<dyn Decryption>();
}
return Err(e);
}
if part.is_null() {
return Ok(());
}
let part_len: CK_ULONG = unsafe { *pul_part_len };
if let Err(e) = internal_digest_update(&mut session, part, part_len) {
let _ = session.cancel_operation::<dyn Decryption>();
return Err(e);
}
Ok(())
}
pub extern "C" fn fn_decrypt_digest_update(
s_handle: CK_SESSION_HANDLE,
encrypted_part: CK_BYTE_PTR,
encrypted_part_len: CK_ULONG,
part: CK_BYTE_PTR,
pul_part_len: CK_ULONG_PTR,
) -> CK_RV {
log_debug!(
"C_DecryptDigestUpdate: s_handle={} encrypted_part={:?} encrypted_part_len={} part={:?} pul_part_len={:?}",
s_handle,
encrypted_part,
encrypted_part_len,
part,
pul_part_len
);
let rv = match decrypt_digest_update(
s_handle,
encrypted_part,
encrypted_part_len,
part,
pul_part_len,
) {
Ok(()) => CKR_OK,
Err(e) => e.rv(),
};
log_debug!("C_DecryptDigestUpdate: ret={}", rv);
rv
}
#[inline(always)]
fn sign_encrypt_update(
s_handle: CK_SESSION_HANDLE,
part: CK_BYTE_PTR,
part_len: CK_ULONG,
encrypted_part: CK_BYTE_PTR,
pul_encrypted_part_len: CK_ULONG_PTR,
) -> Result<()> {
let rstate = STATE.rlock()?;
let mut session = rstate.get_session_mut(s_handle)?;
let res = session
.check_op::<dyn Sign>()
.and_then(|_| session.check_op::<dyn Encryption>())
.and_then(|_| {
internal_encrypt_update(
&mut session,
part,
part_len,
encrypted_part,
pul_encrypted_part_len,
)
});
if let Err(e) = res {
if e.kind() != crate::error::ErrorKind::BufferTooSmall {
let _ = session.cancel_operation::<dyn Sign>();
let _ = session.cancel_operation::<dyn Encryption>();
}
return Err(e);
}
if encrypted_part.is_null() {
return Ok(());
}
if let Err(e) = internal_sign_update(&mut session, part, part_len) {
let _ = session.cancel_operation::<dyn Encryption>();
return Err(e);
}
Ok(())
}
pub extern "C" fn fn_sign_encrypt_update(
s_handle: CK_SESSION_HANDLE,
part: CK_BYTE_PTR,
part_len: CK_ULONG,
encrypted_part: CK_BYTE_PTR,
pul_encrypted_part_len: CK_ULONG_PTR,
) -> CK_RV {
log_debug!(
"C_SignEncryptUpdate: s_handle={} part={:?} part_len={} encrypted_part={:?} pul_encrypted_part_len={:?}",
s_handle,
part,
part_len,
encrypted_part,
pul_encrypted_part_len
);
let rv = match sign_encrypt_update(
s_handle,
part,
part_len,
encrypted_part,
pul_encrypted_part_len,
) {
Ok(()) => CKR_OK,
Err(e) => e.rv(),
};
log_debug!("C_SignEncryptUpdate: ret={}", rv);
rv
}
#[inline(always)]
fn decrypt_verify_update(
s_handle: CK_SESSION_HANDLE,
encrypted_part: CK_BYTE_PTR,
encrypted_part_len: CK_ULONG,
part: CK_BYTE_PTR,
pul_part_len: CK_ULONG_PTR,
) -> Result<()> {
let rstate = STATE.rlock()?;
let mut session = rstate.get_session_mut(s_handle)?;
let res = session
.check_op::<dyn Verify>()
.and_then(|_| session.check_op::<dyn Decryption>())
.and_then(|_| {
internal_decrypt_update(
&mut session,
encrypted_part,
encrypted_part_len,
part,
pul_part_len,
)
});
if let Err(e) = res {
if e.kind() != crate::error::ErrorKind::BufferTooSmall {
let _ = session.cancel_operation::<dyn Verify>();
let _ = session.cancel_operation::<dyn Decryption>();
}
return Err(e);
}
if part.is_null() {
return Ok(());
}
let part_len: CK_ULONG = unsafe { *pul_part_len };
if let Err(e) = internal_verify_update(&mut session, part, part_len) {
let _ = session.cancel_operation::<dyn Decryption>();
return Err(e);
}
Ok(())
}
pub extern "C" fn fn_decrypt_verify_update(
s_handle: CK_SESSION_HANDLE,
encrypted_part: CK_BYTE_PTR,
encrypted_part_len: CK_ULONG,
part: CK_BYTE_PTR,
pul_part_len: CK_ULONG_PTR,
) -> CK_RV {
log_debug!(
"C_DecryptVerifyUpdate: s_handle={} encrypted_part={:?} encrypted_part_len={} part={:?} pul_part_len={:?}",
s_handle,
encrypted_part,
encrypted_part_len,
part,
pul_part_len
);
let rv = match decrypt_verify_update(
s_handle,
encrypted_part,
encrypted_part_len,
part,
pul_part_len,
) {
Ok(()) => CKR_OK,
Err(e) => e.rv(),
};
log_debug!("C_DecryptVerifyUpdate: ret={}", rv);
rv
}