Skip to content

Commit 543dd75

Browse files
Added derive_keys function to get additional derived keys from mechanism params
Signed-off-by: Jacob Prud'homme <[email protected]>
1 parent f0a2974 commit 543dd75

File tree

3 files changed

+127
-32
lines changed

3 files changed

+127
-32
lines changed

cryptoki/src/mechanism/kbkdf.rs

Lines changed: 75 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
//! Mechanisms of NIST key-based key derive functions (SP 800-108, informally KBKDF)
44
//! See: <https://docs.oasis-open.org/pkcs11/pkcs11-curr/v3.0/os/pkcs11-curr-v3.0-os.html#_Toc30061446>
55
6-
use std::{convert::TryInto, marker::PhantomData, ptr};
6+
use core::{convert::TryInto, marker::PhantomData, ptr, slice};
77

88
use cryptoki_sys::{
99
CK_ATTRIBUTE, CK_ATTRIBUTE_PTR, CK_DERIVED_KEY, CK_DERIVED_KEY_PTR, CK_OBJECT_HANDLE,
@@ -158,14 +158,12 @@ impl<'a> KbkdfCounterParams<'a> {
158158
pub fn new(
159159
prf_mechanism: MechanismType,
160160
prf_data_params: Vec<PrfDataParam<'a>>,
161-
additional_derived_keys: Vec<DerivedKey<'a>>,
161+
mut additional_derived_keys: Vec<DerivedKey<'a>>,
162162
) -> Self {
163163
let prf_data_params: Vec<CK_PRF_DATA_PARAM> =
164-
prf_data_params.into_iter().map(Into::into).collect();
165-
let additional_derived_keys: Vec<CK_DERIVED_KEY> = additional_derived_keys
166-
.into_iter()
167-
.map(Into::into)
168-
.collect();
164+
prf_data_params.iter().map(Into::into).collect();
165+
let additional_derived_keys: Vec<CK_DERIVED_KEY> =
166+
additional_derived_keys.iter_mut().map(Into::into).collect();
169167

170168
Self {
171169
inner: cryptoki_sys::CK_SP800_108_KDF_PARAMS {
@@ -184,6 +182,23 @@ impl<'a> KbkdfCounterParams<'a> {
184182
_marker: PhantomData,
185183
}
186184
}
185+
186+
/// The additional keys derived by the KDF, as per the params
187+
pub fn additional_derived_keys(&self) -> Vec<CK_OBJECT_HANDLE> {
188+
let derived_keys = unsafe {
189+
slice::from_raw_parts(
190+
self.inner.pAdditionalDerivedKeys,
191+
self.inner.ulAdditionalDerivedKeys as _,
192+
)
193+
};
194+
195+
unsafe {
196+
derived_keys
197+
.iter()
198+
.map(|derived_key| *derived_key.phKey)
199+
.collect()
200+
}
201+
}
187202
}
188203

189204
/// NIST SP 800-108 (aka KBKDF) feedback-mode parameters.
@@ -214,14 +229,12 @@ impl<'a> KbkdfFeedbackParams<'a> {
214229
prf_mechanism: MechanismType,
215230
prf_data_params: Vec<PrfDataParam<'a>>,
216231
iv: Option<&'a [u8]>,
217-
additional_derived_keys: Vec<DerivedKey<'a>>,
232+
mut additional_derived_keys: Vec<DerivedKey<'a>>,
218233
) -> Self {
219234
let prf_data_params: Vec<CK_PRF_DATA_PARAM> =
220-
prf_data_params.into_iter().map(Into::into).collect();
221-
let additional_derived_keys: Vec<CK_DERIVED_KEY> = additional_derived_keys
222-
.into_iter()
223-
.map(Into::into)
224-
.collect();
235+
prf_data_params.iter().map(Into::into).collect();
236+
let additional_derived_keys: Vec<CK_DERIVED_KEY> =
237+
additional_derived_keys.iter_mut().map(Into::into).collect();
225238

226239
Self {
227240
inner: cryptoki_sys::CK_SP800_108_FEEDBACK_KDF_PARAMS {
@@ -246,6 +259,23 @@ impl<'a> KbkdfFeedbackParams<'a> {
246259
_marker: PhantomData,
247260
}
248261
}
262+
263+
/// The additional keys derived by the KDF, as per the params
264+
pub fn additional_derived_keys(&self) -> Vec<CK_OBJECT_HANDLE> {
265+
let derived_keys = unsafe {
266+
slice::from_raw_parts(
267+
self.inner.pAdditionalDerivedKeys,
268+
self.inner.ulAdditionalDerivedKeys as _,
269+
)
270+
};
271+
272+
unsafe {
273+
derived_keys
274+
.iter()
275+
.map(|derived_key| *derived_key.phKey)
276+
.collect()
277+
}
278+
}
249279
}
250280

251281
/// NIST SP 800-108 (aka KBKDF) double pipeline-mode parameters.
@@ -273,14 +303,12 @@ impl<'a> KbkdfDoublePipelineParams<'a> {
273303
pub fn new(
274304
prf_mechanism: MechanismType,
275305
prf_data_params: Vec<PrfDataParam<'a>>,
276-
additional_derived_keys: Vec<DerivedKey<'a>>,
306+
mut additional_derived_keys: Vec<DerivedKey<'a>>,
277307
) -> Self {
278308
let prf_data_params: Vec<CK_PRF_DATA_PARAM> =
279-
prf_data_params.into_iter().map(Into::into).collect();
280-
let additional_derived_keys: Vec<CK_DERIVED_KEY> = additional_derived_keys
281-
.into_iter()
282-
.map(Into::into)
283-
.collect();
309+
prf_data_params.iter().map(Into::into).collect();
310+
let additional_derived_keys: Vec<CK_DERIVED_KEY> =
311+
additional_derived_keys.iter_mut().map(Into::into).collect();
284312

285313
Self {
286314
inner: cryptoki_sys::CK_SP800_108_KDF_PARAMS {
@@ -299,10 +327,27 @@ impl<'a> KbkdfDoublePipelineParams<'a> {
299327
_marker: PhantomData,
300328
}
301329
}
330+
331+
/// The additional keys derived by the KDF, as per the params
332+
pub fn additional_derived_keys(&self) -> Vec<CK_OBJECT_HANDLE> {
333+
let derived_keys = unsafe {
334+
slice::from_raw_parts(
335+
self.inner.pAdditionalDerivedKeys,
336+
self.inner.ulAdditionalDerivedKeys as _,
337+
)
338+
};
339+
340+
unsafe {
341+
derived_keys
342+
.iter()
343+
.map(|derived_key| *derived_key.phKey)
344+
.collect()
345+
}
346+
}
302347
}
303348

304-
impl<'a> From<PrfDataParam<'a>> for CK_PRF_DATA_PARAM {
305-
fn from(value: PrfDataParam<'a>) -> Self {
349+
impl<'a> From<&PrfDataParam<'a>> for CK_PRF_DATA_PARAM {
350+
fn from(value: &PrfDataParam<'a>) -> Self {
306351
Self {
307352
type_: match value {
308353
PrfDataParam::IterationVariable => CK_SP800_108_ITERATION_VARIABLE,
@@ -312,8 +357,8 @@ impl<'a> From<PrfDataParam<'a>> for CK_PRF_DATA_PARAM {
312357
},
313358
pValue: match value {
314359
PrfDataParam::IterationVariable => ptr::null_mut(),
315-
PrfDataParam::Counter(inner) => &inner as *const _ as *mut _,
316-
PrfDataParam::DkmLength(inner) => &inner as *const _ as *mut _,
360+
PrfDataParam::Counter(inner) => inner as *const _ as *mut _,
361+
PrfDataParam::DkmLength(inner) => inner as *const _ as *mut _,
317362
PrfDataParam::ByteArray(data) => data.as_ptr() as *mut _,
318363
},
319364
ulValueLen: match value {
@@ -331,17 +376,17 @@ impl<'a> From<PrfDataParam<'a>> for CK_PRF_DATA_PARAM {
331376
}
332377
}
333378

334-
impl<'a> From<PrfCounterDataParam<'a>> for CK_PRF_DATA_PARAM {
335-
fn from(value: PrfCounterDataParam<'a>) -> Self {
379+
impl<'a> From<&PrfCounterDataParam<'a>> for CK_PRF_DATA_PARAM {
380+
fn from(value: &PrfCounterDataParam<'a>) -> Self {
336381
Self {
337382
type_: match value {
338383
PrfCounterDataParam::IterationVariable(_) => CK_SP800_108_ITERATION_VARIABLE,
339384
PrfCounterDataParam::DkmLength(_) => CK_SP800_108_DKM_LENGTH,
340385
PrfCounterDataParam::ByteArray(_) => CK_SP800_108_BYTE_ARRAY,
341386
},
342387
pValue: match value {
343-
PrfCounterDataParam::IterationVariable(inner) => &inner as *const _ as *mut _,
344-
PrfCounterDataParam::DkmLength(inner) => &inner as *const _ as *mut _,
388+
PrfCounterDataParam::IterationVariable(inner) => inner as *const _ as *mut _,
389+
PrfCounterDataParam::DkmLength(inner) => inner as *const _ as *mut _,
345390
PrfCounterDataParam::ByteArray(data) => data.as_ptr() as *mut _,
346391
},
347392
ulValueLen: match value {
@@ -360,9 +405,9 @@ impl<'a> From<PrfCounterDataParam<'a>> for CK_PRF_DATA_PARAM {
360405
}
361406
}
362407

363-
impl<'a> From<DerivedKey<'a>> for CK_DERIVED_KEY {
364-
fn from(mut value: DerivedKey<'a>) -> Self {
365-
let template: Vec<CK_ATTRIBUTE> = value.template.iter().map(|attr| attr.into()).collect();
408+
impl<'a> From<&mut DerivedKey<'a>> for CK_DERIVED_KEY {
409+
fn from(value: &mut DerivedKey<'a>) -> Self {
410+
let template: Vec<CK_ATTRIBUTE> = value.template.iter().map(Into::into).collect();
366411

367412
Self {
368413
pTemplate: template.as_ptr() as CK_ATTRIBUTE_PTR,

cryptoki/src/mechanism/mod.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ mod mechanism_info;
1212
pub mod rsa;
1313
pub mod vendor_defined;
1414

15-
use crate::error::Error;
1615
use cryptoki_sys::*;
1716
use log::error;
1817
use std::convert::{TryFrom, TryInto};
@@ -23,7 +22,9 @@ use std::ops::Deref;
2322
use std::ptr::null_mut;
2423
use vendor_defined::VendorDefinedMechanism;
2524

25+
use crate::error::Error;
2626
use crate::mechanism::rsa::PkcsOaepParams;
27+
use crate::object::ObjectHandle;
2728
pub use mechanism_info::MechanismInfo;
2829

2930
#[derive(Copy, Debug, Clone, PartialEq, Eq)]
@@ -1283,3 +1284,25 @@ impl MessageParam<'_> {
12831284
}
12841285
}
12851286
}
1287+
1288+
/// Trait for mechanism types that define additional keys to be derived in their parameters
1289+
pub trait HasAdditionalDerivedKeys {
1290+
/// Get the object handles for the additional keys that were derived
1291+
fn additional_derived_keys(&self) -> Vec<ObjectHandle>;
1292+
}
1293+
1294+
impl HasAdditionalDerivedKeys for &Mechanism<'_> {
1295+
fn additional_derived_keys(&self) -> Vec<ObjectHandle> {
1296+
let additional_derived_keys = match self {
1297+
Mechanism::KbkdfCounter(params) => params.additional_derived_keys(),
1298+
Mechanism::KbkdfFeedback(params) => params.additional_derived_keys(),
1299+
Mechanism::KbkdfDoublePipeline(params) => params.additional_derived_keys(),
1300+
_ => unimplemented!("The given mechanism doesn't define additional keys to derive"), // TODO: this or return an option?
1301+
};
1302+
1303+
additional_derived_keys
1304+
.into_iter()
1305+
.map(ObjectHandle::new)
1306+
.collect()
1307+
}
1308+
}

cryptoki/src/session/key_management.rs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
55
use crate::context::Function;
66
use crate::error::{Result, Rv};
7-
use crate::mechanism::Mechanism;
7+
use crate::mechanism::{HasAdditionalDerivedKeys as _, Mechanism};
88
use crate::object::{Attribute, ObjectHandle};
99
use crate::session::Session;
1010
use cryptoki_sys::{CK_ATTRIBUTE, CK_MECHANISM, CK_MECHANISM_PTR};
@@ -93,6 +93,33 @@ impl Session {
9393
Ok(ObjectHandle::new(handle))
9494
}
9595

96+
/// Derives multiple keys from a base key
97+
pub fn derive_keys(
98+
&self,
99+
mechanism: &Mechanism,
100+
base_key: ObjectHandle,
101+
template: &[Attribute],
102+
) -> Result<(ObjectHandle, Vec<ObjectHandle>)> {
103+
let mut c_mechanism: CK_MECHANISM = mechanism.into();
104+
let mut template: Vec<CK_ATTRIBUTE> = template.iter().map(|attr| attr.into()).collect();
105+
let mut handle = 0;
106+
unsafe {
107+
Rv::from(get_pkcs11!(self.client(), C_DeriveKey)(
108+
self.handle(),
109+
&mut c_mechanism as CK_MECHANISM_PTR,
110+
base_key.handle(),
111+
template.as_mut_ptr(),
112+
template.len().try_into()?,
113+
&mut handle,
114+
))
115+
.into_result(Function::DeriveKey)?;
116+
}
117+
118+
let additional_key_handles = mechanism.additional_derived_keys();
119+
120+
Ok((ObjectHandle::new(handle), additional_key_handles))
121+
}
122+
96123
/// Wrap key
97124
pub fn wrap_key(
98125
&self,

0 commit comments

Comments
 (0)