Skip to content

Commit 5714b0b

Browse files
committed
Add Encapsulation/Decapsulation operation
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
1 parent 227663e commit 5714b0b

File tree

3 files changed

+106
-1
lines changed

3 files changed

+106
-1
lines changed

cryptoki/src/mechanism/mechanism_info.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ bitflags! {
3232
const MESSAGE_ENCRYPT = CKF_MESSAGE_ENCRYPT;
3333
const MESSAGE_DECRYPT = CKF_MESSAGE_DECRYPT;
3434
const MULTI_MESSAGE = CKF_MULTI_MESSAGE;
35+
const ENCAPSULATE = CKF_ENCAPSULATE;
36+
const DECAPSULATE = CKF_DECAPSULATE;
3537
}
3638
}
3739

@@ -252,6 +254,18 @@ impl MechanismInfo {
252254
pub fn multi_message(&self) -> bool {
253255
self.flags.contains(MechanismInfoFlags::MULTI_MESSAGE)
254256
}
257+
258+
/// True if the mechanism can be used to encapsulate other keys
259+
///
260+
pub fn encapsulate(&self) -> bool {
261+
self.flags.contains(MechanismInfoFlags::ENCAPSULATE)
262+
}
263+
264+
/// True if the mechanism can be used to decapsulate other keys
265+
///
266+
pub fn decapsulate(&self) -> bool {
267+
self.flags.contains(MechanismInfoFlags::DECAPSULATE)
268+
}
255269
}
256270

257271
impl std::fmt::Display for MechanismInfo {
@@ -294,7 +308,7 @@ HW | ENCRYPT | DECRYPT | DIGEST | SIGN | SIGN_RECOVER | VERIFY | \
294308
VERIFY_RECOVER | GENERATE | GENERATE_KEY_PAIR | WRAP | UNWRAP | DERIVE | \
295309
EXTENSION | EC_F_P | EC_F_2M | EC_ECPARAMETERS | EC_NAMEDCURVE | \
296310
EC_OID | EC_UNCOMPRESS | EC_COMPRESS | MESSAGE_ENCRYPT | MESSAGE_DECRYPT | \
297-
MULTI_MESSAGE";
311+
MULTI_MESSAGE | ENCAPSULATE | DECAPSULATE";
298312
let all = MechanismInfoFlags::all();
299313
let observed = format!("{all:#?}");
300314
println!("{observed}");

cryptoki/src/session/encapsulation.rs

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
// Copyright 2025 Contributors to the Parsec project.
2+
// SPDX-License-Identifier: Apache-2.0
3+
//! Encapsulating/decapsulating data
4+
5+
use crate::context::Function;
6+
use crate::error::{Result, Rv};
7+
use crate::mechanism::Mechanism;
8+
use crate::object::{Attribute, ObjectHandle};
9+
use crate::session::Session;
10+
use cryptoki_sys::*;
11+
use std::convert::TryInto;
12+
13+
impl Session {
14+
/// Encapsulate key
15+
pub fn encapsulate_key(
16+
&self,
17+
mechanism: &Mechanism,
18+
publickey: ObjectHandle,
19+
template: &[Attribute],
20+
) -> Result<(Vec<u8>, ObjectHandle)> {
21+
let mut mechanism: CK_MECHANISM = mechanism.into();
22+
let mut template: Vec<CK_ATTRIBUTE> = template.iter().map(|attr| attr.into()).collect();
23+
let mut encapsulated_len = 0;
24+
let mut handle = 0;
25+
26+
// Get the output buffer length
27+
unsafe {
28+
Rv::from(get_pkcs11!(self.client(), C_EncapsulateKey)(
29+
self.handle(),
30+
&mut mechanism as CK_MECHANISM_PTR,
31+
publickey.handle(),
32+
template.as_mut_ptr(),
33+
template.len().try_into()?,
34+
std::ptr::null_mut(),
35+
&mut encapsulated_len,
36+
&mut handle,
37+
))
38+
.into_result(Function::EncapsulateKey)?;
39+
}
40+
41+
let mut encapsulated = vec![0; encapsulated_len.try_into()?];
42+
43+
unsafe {
44+
Rv::from(get_pkcs11!(self.client(), C_EncapsulateKey)(
45+
self.handle(),
46+
&mut mechanism as CK_MECHANISM_PTR,
47+
publickey.handle(),
48+
template.as_mut_ptr(),
49+
template.len().try_into()?,
50+
encapsulated.as_mut_ptr(),
51+
&mut encapsulated_len,
52+
&mut handle,
53+
))
54+
.into_result(Function::EncapsulateKey)?;
55+
}
56+
57+
encapsulated.resize(encapsulated_len.try_into()?, 0);
58+
59+
Ok((encapsulated, ObjectHandle::new(handle)))
60+
}
61+
62+
/// Decapsulate key
63+
pub fn decapsulate_key(
64+
&self,
65+
mechanism: &Mechanism,
66+
privatekey: ObjectHandle,
67+
template: &[Attribute],
68+
ciphertext: &[u8],
69+
) -> Result<ObjectHandle> {
70+
let mut mechanism: CK_MECHANISM = mechanism.into();
71+
let mut template: Vec<CK_ATTRIBUTE> = template.iter().map(|attr| attr.into()).collect();
72+
let mut handle = 0;
73+
74+
unsafe {
75+
Rv::from(get_pkcs11!(self.client(), C_DecapsulateKey)(
76+
self.handle(),
77+
&mut mechanism as CK_MECHANISM_PTR,
78+
privatekey.handle(),
79+
template.as_mut_ptr(),
80+
template.len().try_into()?,
81+
ciphertext.as_ptr() as *mut u8,
82+
ciphertext.len().try_into()?,
83+
&mut handle,
84+
))
85+
.into_result(Function::DecapsulateKey)?;
86+
}
87+
88+
Ok(ObjectHandle::new(handle))
89+
}
90+
}

cryptoki/src/session/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use std::marker::PhantomData;
1010

1111
mod decryption;
1212
mod digesting;
13+
mod encapsulation;
1314
mod encryption;
1415
mod key_management;
1516
mod message_decryption;

0 commit comments

Comments
 (0)