Skip to content

Commit 5023380

Browse files
committed
Implement message sign/verify functions
Signed-off-by: Jakub Jelen <[email protected]>
1 parent b6aad9d commit 5023380

File tree

3 files changed

+270
-1
lines changed

3 files changed

+270
-1
lines changed

cryptoki/src/mechanism/mechanism_info.rs

+17-1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ bitflags! {
3131
const EC_COMPRESS = CKF_EC_COMPRESS;
3232
const MESSAGE_ENCRYPT = CKF_MESSAGE_ENCRYPT;
3333
const MESSAGE_DECRYPT = CKF_MESSAGE_DECRYPT;
34+
const MESSAGE_SIGN = CKF_MESSAGE_SIGN;
35+
const MESSAGE_VERIFY = CKF_MESSAGE_VERIFY;
3436
const MULTI_MESSAGE = CKF_MULTI_MESSAGE;
3537
}
3638
}
@@ -246,6 +248,20 @@ impl MechanismInfo {
246248
self.flags.contains(MechanismInfoFlags::MESSAGE_DECRYPT)
247249
}
248250

251+
/// True if the mechanism can be used to sign messages
252+
///
253+
/// See [`Session::sign_message`](crate::session::Session::sign_message)
254+
pub fn message_sign(&self) -> bool {
255+
self.flags.contains(MechanismInfoFlags::MESSAGE_SIGN)
256+
}
257+
258+
/// True if the mechanism can be used to verify signed messages
259+
///
260+
/// See [`Session::decrypt`](crate::session::Session::verify_message)
261+
pub fn message_verify(&self) -> bool {
262+
self.flags.contains(MechanismInfoFlags::MESSAGE_VERIFY)
263+
}
264+
249265
/// True if the mechanism can be used with encrypt/decrypt_message_begin API.
250266
/// One of message_* flag must also be set.
251267
///
@@ -294,7 +310,7 @@ HW | ENCRYPT | DECRYPT | DIGEST | SIGN | SIGN_RECOVER | VERIFY | \
294310
VERIFY_RECOVER | GENERATE | GENERATE_KEY_PAIR | WRAP | UNWRAP | DERIVE | \
295311
EXTENSION | EC_F_P | EC_F_2M | EC_ECPARAMETERS | EC_NAMEDCURVE | \
296312
EC_OID | EC_UNCOMPRESS | EC_COMPRESS | MESSAGE_ENCRYPT | MESSAGE_DECRYPT | \
297-
MULTI_MESSAGE";
313+
MESSAGE_SIGN | MESSAGE_VERIFY | MULTI_MESSAGE";
298314
let all = MechanismInfoFlags::all();
299315
let observed = format!("{all:#?}");
300316
println!("{observed}");
+252
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
// Copyright 2025 Contributors to the Parsec project.
2+
// SPDX-License-Identifier: Apache-2.0
3+
//! Message Signing/Verification and authentication functions
4+
5+
use crate::context::Function;
6+
use crate::error::{Result, Rv};
7+
use crate::mechanism::{Mechanism, MessageParam};
8+
use crate::object::ObjectHandle;
9+
use crate::session::Session;
10+
use cryptoki_sys::*;
11+
use std::convert::TryInto;
12+
13+
impl Session {
14+
/// Prepare a session for one or more Message-based signature using the same mechanism and key
15+
pub fn message_sign_init(&self, mechanism: &Mechanism, key: ObjectHandle) -> Result<()> {
16+
let mut mechanism: CK_MECHANISM = mechanism.into();
17+
18+
unsafe {
19+
Rv::from(get_pkcs11!(self.client(), C_MessageSignInit)(
20+
self.handle(),
21+
&mut mechanism as CK_MECHANISM_PTR,
22+
key.handle(),
23+
))
24+
.into_result(Function::MessageSignInit)?;
25+
}
26+
27+
Ok(())
28+
}
29+
30+
/// Sign a message in single part
31+
pub fn sign_message(
32+
&self,
33+
param: &MessageParam,
34+
data: &[u8],
35+
) -> Result<Vec<u8>> {
36+
let mut signature_len = 0;
37+
38+
// Get the output buffer length
39+
unsafe {
40+
Rv::from(get_pkcs11!(self.client(), C_SignMessage)(
41+
self.handle(),
42+
param.as_ptr(),
43+
param.len(),
44+
data.as_ptr() as *mut u8,
45+
data.len().try_into()?,
46+
std::ptr::null_mut(),
47+
&mut signature_len,
48+
))
49+
.into_result(Function::SignMessage)?;
50+
}
51+
52+
let mut signature = vec![0; signature_len.try_into()?];
53+
54+
unsafe {
55+
Rv::from(get_pkcs11!(self.client(), C_SignMessage)(
56+
self.handle(),
57+
param.as_ptr(),
58+
param.len(),
59+
data.as_ptr() as *mut u8,
60+
data.len().try_into()?,
61+
signature.as_mut_ptr(),
62+
&mut signature_len,
63+
))
64+
.into_result(Function::SignMessage)?;
65+
}
66+
67+
signature.resize(signature_len.try_into()?, 0);
68+
69+
Ok(signature)
70+
}
71+
72+
/// Begin multi-part message signature operation
73+
pub fn sign_message_begin(&self, param: MessageParam) -> Result<()> {
74+
unsafe {
75+
Rv::from(get_pkcs11!(self.client(), C_SignMessageBegin)(
76+
self.handle(),
77+
param.as_ptr(),
78+
param.len(),
79+
))
80+
.into_result(Function::SignMessageBegin)
81+
}
82+
}
83+
84+
/// Continue mutli-part message signature operation
85+
pub fn sign_message_next(
86+
&self,
87+
param: MessageParam,
88+
data: &[u8],
89+
end: bool,
90+
) -> Result<Option<Vec<u8>>> {
91+
if ! end {
92+
// Just pass in the data
93+
unsafe {
94+
Rv::from(get_pkcs11!(self.client(), C_SignMessageNext)(
95+
self.handle(),
96+
param.as_ptr(),
97+
param.len(),
98+
data.as_ptr() as *mut u8,
99+
data.len().try_into()?,
100+
std::ptr::null_mut(),
101+
std::ptr::null_mut(),
102+
))
103+
.into_result(Function::SignMessageNext)?;
104+
}
105+
return Ok(None)
106+
}
107+
let mut signature_len = 0;
108+
unsafe {
109+
Rv::from(get_pkcs11!(self.client(), C_SignMessageNext)(
110+
self.handle(),
111+
param.as_ptr(),
112+
param.len(),
113+
data.as_ptr() as *mut u8,
114+
data.len().try_into()?,
115+
std::ptr::null_mut(),
116+
&mut signature_len,
117+
))
118+
.into_result(Function::SignMessageNext)?;
119+
}
120+
121+
let mut signature = vec![0; signature_len.try_into()?];
122+
123+
unsafe {
124+
Rv::from(get_pkcs11!(self.client(), C_SignMessageNext)(
125+
self.handle(),
126+
param.as_ptr(),
127+
param.len(),
128+
data.as_ptr() as *mut u8,
129+
data.len().try_into()?,
130+
signature.as_mut_ptr(),
131+
&mut signature_len,
132+
))
133+
.into_result(Function::SignMessageNext)?;
134+
}
135+
136+
signature.resize(signature_len.try_into()?, 0);
137+
138+
Ok(Some(signature))
139+
}
140+
141+
/// Finalize mutli-part message signature process
142+
pub fn message_sign_final(&self) -> Result<()> {
143+
unsafe {
144+
Rv::from(get_pkcs11!(self.client(), C_MessageSignFinal)(
145+
self.handle(),
146+
))
147+
.into_result(Function::MessageSignFinal)
148+
}
149+
}
150+
151+
/// Prepare a session for one or more Message-based verifications using the same mechanism and key
152+
pub fn message_verify_init(&self, mechanism: &Mechanism, key: ObjectHandle) -> Result<()> {
153+
let mut mechanism: CK_MECHANISM = mechanism.into();
154+
155+
unsafe {
156+
Rv::from(get_pkcs11!(self.client(), C_MessageVerifyInit)(
157+
self.handle(),
158+
&mut mechanism as CK_MECHANISM_PTR,
159+
key.handle(),
160+
))
161+
.into_result(Function::MessageVerifyInit)?;
162+
}
163+
164+
Ok(())
165+
}
166+
167+
/// Verify message in single-part
168+
pub fn verify_message(
169+
&self,
170+
param: &MessageParam,
171+
data: &[u8],
172+
signature: &[u8],
173+
) -> Result<()> {
174+
unsafe {
175+
Rv::from(get_pkcs11!(self.client(), C_VerifyMessage)(
176+
self.handle(),
177+
param.as_ptr(),
178+
param.len(),
179+
data.as_ptr() as *mut u8,
180+
data.len().try_into()?,
181+
signature.as_ptr() as *mut u8,
182+
signature.len().try_into()?,
183+
))
184+
.into_result(Function::VerifyMessage)?;
185+
}
186+
Ok(())
187+
}
188+
189+
/// Begin multi-part message signature verification operation
190+
pub fn verify_message_begin(&self, param: MessageParam) -> Result<()> {
191+
unsafe {
192+
Rv::from(get_pkcs11!(self.client(), C_VerifyMessageBegin)(
193+
self.handle(),
194+
param.as_ptr(),
195+
param.len(),
196+
))
197+
.into_result(Function::VerifyMessageBegin)
198+
}
199+
}
200+
201+
/// Continue mutli-part message signature verification operation
202+
pub fn verify_message_next(
203+
&self,
204+
param: MessageParam,
205+
data: &[u8],
206+
signature: Option<&[u8]>,
207+
) -> Result<()> {
208+
match signature {
209+
None => {
210+
// Just pass in the data
211+
unsafe {
212+
Rv::from(get_pkcs11!(self.client(), C_VerifyMessageNext)(
213+
self.handle(),
214+
param.as_ptr(),
215+
param.len(),
216+
data.as_ptr() as *mut u8,
217+
data.len().try_into()?,
218+
std::ptr::null_mut(),
219+
0,
220+
))
221+
.into_result(Function::VerifyMessageNext)?;
222+
}
223+
return Ok(())
224+
},
225+
Some(s) => {
226+
unsafe {
227+
Rv::from(get_pkcs11!(self.client(), C_VerifyMessageNext)(
228+
self.handle(),
229+
param.as_ptr(),
230+
param.len(),
231+
data.as_ptr() as *mut u8,
232+
data.len().try_into()?,
233+
s.as_ptr() as *mut u8,
234+
s.len().try_into()?,
235+
))
236+
.into_result(Function::VerifyMessageNext)?;
237+
}
238+
}
239+
}
240+
Ok(())
241+
}
242+
243+
/// Finalize mutli-part message signature verification process
244+
pub fn message_verify_final(&self) -> Result<()> {
245+
unsafe {
246+
Rv::from(get_pkcs11!(self.client(), C_MessageVerifyFinal)(
247+
self.handle(),
248+
))
249+
.into_result(Function::MessageVerifyFinal)
250+
}
251+
}
252+
}

cryptoki/src/session/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ mod encryption;
1414
mod key_management;
1515
mod message_decryption;
1616
mod message_encryption;
17+
mod message_signing;
1718
mod object_management;
1819
mod random;
1920
mod session_info;

0 commit comments

Comments
 (0)