Skip to content

Commit 0054bb7

Browse files
committed
Add Encapsulation/Decapsulation operation
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
1 parent 26069d4 commit 0054bb7

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
@@ -34,6 +34,8 @@ bitflags! {
3434
const MESSAGE_SIGN = CKF_MESSAGE_SIGN;
3535
const MESSAGE_VERIFY = CKF_MESSAGE_VERIFY;
3636
const MULTI_MESSAGE = CKF_MULTI_MESSAGE;
37+
const ENCAPSULATE = CKF_ENCAPSULATE;
38+
const DECAPSULATE = CKF_DECAPSULATE;
3739
}
3840
}
3941

@@ -268,6 +270,18 @@ impl MechanismInfo {
268270
pub fn multi_message(&self) -> bool {
269271
self.flags.contains(MechanismInfoFlags::MULTI_MESSAGE)
270272
}
273+
274+
/// True if the mechanism can be used to encapsulate other keys
275+
///
276+
pub fn encapsulate(&self) -> bool {
277+
self.flags.contains(MechanismInfoFlags::ENCAPSULATE)
278+
}
279+
280+
/// True if the mechanism can be used to decapsulate other keys
281+
///
282+
pub fn decapsulate(&self) -> bool {
283+
self.flags.contains(MechanismInfoFlags::DECAPSULATE)
284+
}
271285
}
272286

273287
impl std::fmt::Display for MechanismInfo {
@@ -310,7 +324,7 @@ HW | ENCRYPT | DECRYPT | DIGEST | SIGN | SIGN_RECOVER | VERIFY | \
310324
VERIFY_RECOVER | GENERATE | GENERATE_KEY_PAIR | WRAP | UNWRAP | DERIVE | \
311325
EXTENSION | EC_F_P | EC_F_2M | EC_ECPARAMETERS | EC_NAMEDCURVE | \
312326
EC_OID | EC_UNCOMPRESS | EC_COMPRESS | MESSAGE_ENCRYPT | MESSAGE_DECRYPT | \
313-
MESSAGE_SIGN | MESSAGE_VERIFY | MULTI_MESSAGE";
327+
MESSAGE_SIGN | MESSAGE_VERIFY | MULTI_MESSAGE | ENCAPSULATE | DECAPSULATE";
314328
let all = MechanismInfoFlags::all();
315329
let observed = format!("{all:#?}");
316330
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)