Skip to content

Commit 6e6e652

Browse files
simo5Gemini
andcommitted
Expose single-part crypto operations
Refactor encryption, decryption, signing, verification, and digesting operations to separate the initialization logic from the single-part execution logic. This exposes `*_single` methods publicly, allowing greater flexibility in operation flows. For example, this supports context-specific user authentication where the operation must be initialized before the authentication step occurs. Co-authored-by: Gemini <gemini@google.com> Signed-off-by: Simo Sorce <simo@redhat.com>
1 parent 1914f61 commit 6e6e652

5 files changed

Lines changed: 81 additions & 51 deletions

File tree

cryptoki/src/session/decryption.rs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,13 @@ impl Session {
1818
key: ObjectHandle,
1919
encrypted_data: &[u8],
2020
) -> Result<Vec<u8>> {
21-
let mut mechanism: CK_MECHANISM = mechanism.into();
22-
let mut data_len = 0;
21+
self.decrypt_init(mechanism, key)?;
22+
self.decrypt_single(encrypted_data)
23+
}
2324

24-
unsafe {
25-
Rv::from(get_pkcs11!(self.client(), C_DecryptInit)(
26-
self.handle(),
27-
&mut mechanism as CK_MECHANISM_PTR,
28-
key.handle(),
29-
))
30-
.into_result(Function::DecryptInit)?;
31-
}
25+
/// Single-part decryption operation, assuming the operation was already initialized.
26+
pub fn decrypt_single(&self, encrypted_data: &[u8]) -> Result<Vec<u8>> {
27+
let mut data_len = 0;
3228

3329
// Get the output buffer length
3430
unsafe {

cryptoki/src/session/digesting.rs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,14 @@ use std::convert::TryInto;
1212

1313
impl Session {
1414
/// 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;
15+
pub fn digest(&self, mechanism: &Mechanism, data: &[u8]) -> Result<Vec<u8>> {
16+
self.digest_init(mechanism)?;
17+
self.digest_single(data)
18+
}
1819

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-
}
20+
/// Digest data in single-part, assuming the operation was already initialized.
21+
pub fn digest_single(&self, data: &[u8]) -> Result<Vec<u8>> {
22+
let mut digest_len = 0;
2623

2724
// Get the output buffer length
2825
unsafe {

cryptoki/src/session/encryption.rs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,13 @@ impl Session {
1818
key: ObjectHandle,
1919
data: &[u8],
2020
) -> Result<Vec<u8>> {
21-
let mut mechanism: CK_MECHANISM = mechanism.into();
22-
let mut encrypted_data_len = 0;
21+
self.encrypt_init(mechanism, key)?;
22+
self.encrypt_single(data)
23+
}
2324

24-
unsafe {
25-
Rv::from(get_pkcs11!(self.client(), C_EncryptInit)(
26-
self.handle(),
27-
&mut mechanism as CK_MECHANISM_PTR,
28-
key.handle(),
29-
))
30-
.into_result(Function::EncryptInit)?;
31-
}
25+
/// Single-part encryption operation, assuming the operation was already initialized.
26+
pub fn encrypt_single(&self, data: &[u8]) -> Result<Vec<u8>> {
27+
let mut encrypted_data_len = 0;
3228

3329
// Get the output buffer length
3430
unsafe {

cryptoki/src/session/signing_macing.rs

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,13 @@ use std::convert::TryInto;
1313
impl Session {
1414
/// Sign data in single-part
1515
pub fn sign(&self, mechanism: &Mechanism, key: ObjectHandle, data: &[u8]) -> Result<Vec<u8>> {
16-
let mut mechanism: CK_MECHANISM = mechanism.into();
17-
let mut signature_len = 0;
16+
self.sign_init(mechanism, key)?;
17+
self.sign_single(data)
18+
}
1819

19-
unsafe {
20-
Rv::from(get_pkcs11!(self.client(), C_SignInit)(
21-
self.handle(),
22-
&mut mechanism as CK_MECHANISM_PTR,
23-
key.handle(),
24-
))
25-
.into_result(Function::SignInit)?;
26-
}
20+
/// Sign data in single-part, assuming the operation was already initialized.
21+
pub fn sign_single(&self, data: &[u8]) -> Result<Vec<u8>> {
22+
let mut signature_len = 0;
2723

2824
// Get the output buffer length
2925
unsafe {
@@ -126,17 +122,12 @@ impl Session {
126122
data: &[u8],
127123
signature: &[u8],
128124
) -> Result<()> {
129-
let mut mechanism: CK_MECHANISM = mechanism.into();
130-
131-
unsafe {
132-
Rv::from(get_pkcs11!(self.client(), C_VerifyInit)(
133-
self.handle(),
134-
&mut mechanism as CK_MECHANISM_PTR,
135-
key.handle(),
136-
))
137-
.into_result(Function::VerifyInit)?;
138-
}
125+
self.verify_init(mechanism, key)?;
126+
self.verify_single(data, signature)
127+
}
139128

129+
/// Verify data in single-part, assuming the operation was already initialized.
130+
pub fn verify_single(&self, data: &[u8], signature: &[u8]) -> Result<()> {
140131
unsafe {
141132
Rv::from(get_pkcs11!(self.client(), C_Verify)(
142133
self.handle(),
@@ -257,4 +248,4 @@ impl Session {
257248

258249
Ok(())
259250
}
260-
}
251+
}

cryptoki/tests/basic.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,56 @@ fn sign_verify_eddsa_with_ed448_schemes() -> TestResult {
239239
Ok(())
240240
}
241241

242+
#[test]
243+
#[serial]
244+
fn sign_verify_single_part() -> TestResult {
245+
let (pkcs11, slot) = init_pins();
246+
247+
// Open a session and log in
248+
let session = pkcs11.open_rw_session(slot)?;
249+
session.login(UserType::User, Some(&AuthPin::new(USER_PIN.into())))?;
250+
251+
// Define parameters for keypair
252+
let public_exponent = vec![0x01, 0x00, 0x01];
253+
let modulus_bits = 2048;
254+
255+
let pub_key_template = vec![
256+
Attribute::Token(true),
257+
Attribute::Private(false),
258+
Attribute::PublicExponent(public_exponent),
259+
Attribute::ModulusBits(modulus_bits.into()),
260+
Attribute::Verify(true),
261+
];
262+
let priv_key_template = vec![Attribute::Token(true), Attribute::Sign(true)];
263+
264+
// Generate keypair
265+
let (pub_key, priv_key) = session.generate_key_pair(
266+
&Mechanism::RsaPkcsKeyPairGen,
267+
&pub_key_template,
268+
&priv_key_template,
269+
)?;
270+
271+
// Data to sign
272+
let data = [0xFF, 0x55, 0xDD, 0x11, 0xBB, 0x33];
273+
274+
// Sign data in a single part using separate init and single call
275+
session.sign_init(&Mechanism::Sha256RsaPkcs, priv_key)?;
276+
let signature = session.sign_single(&data)?;
277+
278+
// Verify signature in a single part using separate init and single call
279+
session.verify_init(&Mechanism::Sha256RsaPkcs, pub_key)?;
280+
session.verify_single(&data, &signature)?;
281+
282+
// Delete keys
283+
session.destroy_object(pub_key)?;
284+
session.destroy_object(priv_key)?;
285+
286+
session.close()?;
287+
pkcs11.finalize()?;
288+
289+
Ok(())
290+
}
291+
242292
#[test]
243293
#[serial]
244294
fn sign_verify_multipart() -> TestResult {

0 commit comments

Comments
 (0)