Skip to content
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
23 changes: 12 additions & 11 deletions cryptoki/src/session/decryption.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,18 @@ impl Session {
key: ObjectHandle,
encrypted_data: &[u8],
) -> Result<Vec<u8>> {
let mut mechanism: CK_MECHANISM = mechanism.into();
let mut data_len = 0;
self.decrypt_init(mechanism, key)?;
self.decrypt_single(encrypted_data)
}

unsafe {
Rv::from(get_pkcs11!(self.client(), C_DecryptInit)(
self.handle(),
&mut mechanism as CK_MECHANISM_PTR,
key.handle(),
))
.into_result(Function::DecryptInit)?;
}
/// Single-part decryption operation.
///
/// This function can be used instead of the single shot related decrypt
/// function when the user needs to perform something like
/// context-specific user authentication after [`Session::decrypt_init`]
/// is called.
pub fn decrypt_single(&self, encrypted_data: &[u8]) -> Result<Vec<u8>> {
let mut data_len = 0;

// Get the output buffer length
unsafe {
Expand Down Expand Up @@ -61,7 +62,7 @@ impl Session {
Ok(data)
}

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

Expand Down
24 changes: 13 additions & 11 deletions cryptoki/src/session/digesting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,19 @@ use std::convert::TryInto;

impl Session {
/// Single-part digesting operation
pub fn digest(&self, m: &Mechanism, data: &[u8]) -> Result<Vec<u8>> {
let mut mechanism: CK_MECHANISM = m.into();
let mut digest_len = 0;
pub fn digest(&self, mechanism: &Mechanism, data: &[u8]) -> Result<Vec<u8>> {
self.digest_init(mechanism)?;
self.digest_single(data)
}

unsafe {
Rv::from(get_pkcs11!(self.client(), C_DigestInit)(
self.handle(),
&mut mechanism as CK_MECHANISM_PTR,
))
.into_result(Function::DigestInit)?;
}
/// Digest data in single-part.
///
/// This function can be used instead of the single shot related digest
/// function when the user needs to perform something like
/// context-specific user authentication after [`Session::digest_init`]
/// is called.
pub fn digest_single(&self, data: &[u8]) -> Result<Vec<u8>> {
let mut digest_len = 0;

// Get the output buffer length
unsafe {
Expand Down Expand Up @@ -54,7 +56,7 @@ impl Session {
Ok(digest)
}

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

Expand Down
23 changes: 12 additions & 11 deletions cryptoki/src/session/encryption.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,18 @@ impl Session {
key: ObjectHandle,
data: &[u8],
) -> Result<Vec<u8>> {
let mut mechanism: CK_MECHANISM = mechanism.into();
let mut encrypted_data_len = 0;
self.encrypt_init(mechanism, key)?;
self.encrypt_single(data)
}

unsafe {
Rv::from(get_pkcs11!(self.client(), C_EncryptInit)(
self.handle(),
&mut mechanism as CK_MECHANISM_PTR,
key.handle(),
))
.into_result(Function::EncryptInit)?;
}
/// Single-part encryption operation.
///
/// This function can be used instead of the single shot related encrypt
/// function when the user needs to perform something like
/// context-specific user authentication after [`Session::encrypt_init`]
/// is called.
pub fn encrypt_single(&self, data: &[u8]) -> Result<Vec<u8>> {
let mut encrypted_data_len = 0;

// Get the output buffer length
unsafe {
Expand Down Expand Up @@ -60,7 +61,7 @@ impl Session {
Ok(encrypted_data)
}

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

Expand Down
45 changes: 23 additions & 22 deletions cryptoki/src/session/signing_macing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,18 @@ use std::convert::TryInto;
impl Session {
/// Sign data in single-part
pub fn sign(&self, mechanism: &Mechanism, key: ObjectHandle, data: &[u8]) -> Result<Vec<u8>> {
let mut mechanism: CK_MECHANISM = mechanism.into();
let mut signature_len = 0;
self.sign_init(mechanism, key)?;
self.sign_single(data)
}

unsafe {
Rv::from(get_pkcs11!(self.client(), C_SignInit)(
self.handle(),
&mut mechanism as CK_MECHANISM_PTR,
key.handle(),
))
.into_result(Function::SignInit)?;
}
/// Sign data in single-part.
///
/// This function can be used instead of the single shot related sign
/// function when the user needs to perform something like
/// context-specific user authentication after [`Session::sign_init`]
/// is called.
pub fn sign_single(&self, data: &[u8]) -> Result<Vec<u8>> {
let mut signature_len = 0;

// Get the output buffer length
unsafe {
Expand Down Expand Up @@ -56,7 +57,7 @@ impl Session {
Ok(signature)
}

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

Expand Down Expand Up @@ -126,17 +127,17 @@ impl Session {
data: &[u8],
signature: &[u8],
) -> 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)?;
}
self.verify_init(mechanism, key)?;
self.verify_single(data, signature)
}

/// Verify data in single-part.
///
/// This function can be used instead of the single shot related verify
/// function when the user needs to perform something like
/// context-specific user authentication after [`Session::verify_init`]
/// is called.
pub fn verify_single(&self, data: &[u8], signature: &[u8]) -> Result<()> {
unsafe {
Rv::from(get_pkcs11!(self.client(), C_Verify)(
self.handle(),
Expand All @@ -149,7 +150,7 @@ impl Session {
}
}

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

Expand Down
123 changes: 123 additions & 0 deletions cryptoki/tests/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,56 @@ fn sign_verify_eddsa_with_ed448_schemes() -> TestResult {
Ok(())
}

#[test]
#[serial]
fn sign_verify_single_part() -> TestResult {
Comment thread
simo5 marked this conversation as resolved.
let (pkcs11, slot) = init_pins();

// Open a session and log in
let session = pkcs11.open_rw_session(slot)?;
session.login(UserType::User, Some(&AuthPin::new(USER_PIN.into())))?;

// Define parameters for keypair
let public_exponent = vec![0x01, 0x00, 0x01];
let modulus_bits = 2048;

let pub_key_template = vec![
Attribute::Token(true),
Attribute::Private(false),
Attribute::PublicExponent(public_exponent),
Attribute::ModulusBits(modulus_bits.into()),
Attribute::Verify(true),
];
let priv_key_template = vec![Attribute::Token(true), Attribute::Sign(true)];

// Generate keypair
let (pub_key, priv_key) = session.generate_key_pair(
&Mechanism::RsaPkcsKeyPairGen,
&pub_key_template,
&priv_key_template,
)?;

// Data to sign
let data = [0xFF, 0x55, 0xDD, 0x11, 0xBB, 0x33];

// Sign data in a single part using separate init and single call
session.sign_init(&Mechanism::Sha256RsaPkcs, priv_key)?;
let signature = session.sign_single(&data)?;

// Verify signature in a single part using separate init and single call
session.verify_init(&Mechanism::Sha256RsaPkcs, pub_key)?;
session.verify_single(&data, &signature)?;

// Delete keys
session.destroy_object(pub_key)?;
session.destroy_object(priv_key)?;

session.close()?;
pkcs11.finalize()?;

Ok(())
}

Comment thread
simo5 marked this conversation as resolved.
#[test]
#[serial]
fn sign_verify_multipart() -> TestResult {
Expand Down Expand Up @@ -480,6 +530,50 @@ fn encrypt_decrypt() -> TestResult {
Ok(())
}

#[test]
#[serial]
fn encrypt_decrypt_single_part() -> TestResult {
let (pkcs11, slot) = init_pins();

// Open a session and log in
let session = pkcs11.open_rw_session(slot)?;
session.login(UserType::User, Some(&AuthPin::new(USER_PIN.into())))?;

// Generate key
let template = vec![
Attribute::Token(true),
Attribute::Private(false),
Attribute::ValueLen(AES128_BLOCK_SIZE),
Attribute::Encrypt(true),
Attribute::Decrypt(true),
];
let key = session.generate_key(&Mechanism::AesKeyGen, &template)?;

// Data to encrypt
let data = vec![
0xFF, 0x55, 0xDD, 0x11, 0xBB, 0x33, 0x99, 0x77, 0xFF, 0x55, 0xDD, 0x11, 0xBB, 0x33, 0x99,
0x77,
];

// Encrypt data in a single part using separate init and single call
session.encrypt_init(&Mechanism::AesEcb, key)?;
let encrypted_data = session.encrypt_single(&data)?;

// Decrypt data in a single part using separate init and single call
session.decrypt_init(&Mechanism::AesEcb, key)?;
let decrypted_data = session.decrypt_single(&encrypted_data)?;

assert_eq!(data, decrypted_data);

// Delete key
session.destroy_object(key)?;

session.close()?;
pkcs11.finalize()?;

Ok(())
}

#[test]
#[serial]
fn encrypt_decrypt_multipart() -> TestResult {
Expand Down Expand Up @@ -2277,6 +2371,35 @@ fn sha256_digest() -> TestResult {
Ok(())
}

#[test]
#[serial]
fn sha256_digest_single_part() -> TestResult {
let (pkcs11, slot) = init_pins();

// open a session
let session = pkcs11.open_rw_session(slot)?;

// log in the session
session.login(UserType::User, Some(&AuthPin::new(USER_PIN.into())))?;

// data to digest
let data = vec![0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF];

let want = [
0x17, 0x22, 0x6b, 0x1f, 0x68, 0xae, 0xba, 0xcd, 0xef, 0x07, 0x46, 0x45, 0x0f, 0x64, 0x28,
0x74, 0x63, 0x8b, 0x29, 0x57, 0x07, 0xef, 0x73, 0xfb, 0x2c, 0x6b, 0xb7, 0xf8, 0x8e, 0x89,
0x92, 0x9f,
];
session.digest_init(&Mechanism::Sha256)?;
let have = session.digest_single(&data)?;
assert_eq!(want[..], have[..]);

session.close()?;
pkcs11.finalize()?;

Ok(())
}

#[test]
#[serial]
fn sha256_digest_multipart() -> TestResult {
Expand Down
Loading