Skip to content

Commit 07ba6f1

Browse files
Removed additional types to match the PKCS#11 spec 1-to-1
Gave up some type safety on which types of PRF data parameters are allowed for which KDF modes, in exchange for being a 1-to-1 binding with the PKCS#11 spec. Depending on the wants of the project, this can be reversed. Signed-off-by: Jacob Prud'homme <[email protected]>
1 parent 90491e1 commit 07ba6f1

File tree

2 files changed

+18
-151
lines changed

2 files changed

+18
-151
lines changed

cryptoki/src/mechanism/kbkdf.rs

Lines changed: 13 additions & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ impl KbkdfDkmLengthFormat {
9595
#[derive(Debug, Clone, Copy)]
9696
pub enum PrfDataParamType<'a> {
9797
/// Identifies location of predefined iteration variable in constructed PRF input data.
98-
IterationVariable,
98+
IterationVariable(Option<&'a KbkdfCounterFormat>),
9999
/// Identifies location of counter in constructed PRF input data.
100100
Counter(&'a KbkdfCounterFormat),
101101
/// Identifies location of DKM (derived key material) length in constructed PRF input data.
@@ -124,11 +124,19 @@ impl<'a> PrfDataParam<'a> {
124124
pub fn new(type_: PrfDataParamType<'a>) -> Self {
125125
Self {
126126
inner: match type_ {
127-
PrfDataParamType::IterationVariable => cryptoki_sys::CK_PRF_DATA_PARAM {
127+
PrfDataParamType::IterationVariable(None) => cryptoki_sys::CK_PRF_DATA_PARAM {
128128
type_: cryptoki_sys::CK_SP800_108_ITERATION_VARIABLE,
129129
pValue: ptr::null_mut(),
130130
ulValueLen: 0,
131131
},
132+
PrfDataParamType::IterationVariable(Some(counter_format)) => {
133+
cryptoki_sys::CK_PRF_DATA_PARAM {
134+
type_: cryptoki_sys::CK_SP800_108_ITERATION_VARIABLE,
135+
pValue: counter_format as *const _ as *mut _,
136+
ulValueLen: size_of::<cryptoki_sys::CK_SP800_108_COUNTER_FORMAT>()
137+
as cryptoki_sys::CK_ULONG,
138+
}
139+
}
132140
PrfDataParamType::Counter(counter_format) => cryptoki_sys::CK_PRF_DATA_PARAM {
133141
type_: cryptoki_sys::CK_SP800_108_COUNTER,
134142
pValue: counter_format as *const _ as *mut _,
@@ -155,67 +163,6 @@ impl<'a> PrfDataParam<'a> {
155163
}
156164
}
157165

158-
/// The type of a segment of input data for the PRF, for a KBKDF operating in counter-mode.
159-
#[derive(Debug, Clone, Copy)]
160-
pub enum PrfCounterDataParamType<'a> {
161-
/// Identifies location of iteration variable (a counter in this case) in constructed PRF input data.
162-
IterationVariable(&'a KbkdfCounterFormat),
163-
/// Identifies location of DKM (derived key material) length in constructed PRF input data.
164-
DkmLength(&'a KbkdfDkmLengthFormat),
165-
/// Identifies location and value of byte array of data in constructed PRF input data.
166-
ByteArray(&'a [u8]),
167-
}
168-
169-
/// A segment of input data for the PRF, to be used to construct a sequence of input.
170-
///
171-
/// Corresponds to CK_PRF_DATA_PARAM in the specific case of the KDF operating in counter-mode.
172-
#[derive(Debug, Clone, Copy)]
173-
#[repr(transparent)]
174-
pub struct PrfCounterDataParam<'a> {
175-
inner: cryptoki_sys::CK_PRF_DATA_PARAM,
176-
/// Marker type to ensure we don't outlive the data
177-
_marker: PhantomData<&'a [u8]>,
178-
}
179-
180-
impl<'a> PrfCounterDataParam<'a> {
181-
/// Construct data parameter for input of the PRF internal to the KBKDF.
182-
///
183-
/// # Arguments
184-
///
185-
/// * `type_` - The specific type and parameters for the data parameter.
186-
pub fn new(type_: PrfCounterDataParamType<'a>) -> Self {
187-
Self {
188-
inner: match type_ {
189-
PrfCounterDataParamType::IterationVariable(counter_format) => {
190-
cryptoki_sys::CK_PRF_DATA_PARAM {
191-
type_: cryptoki_sys::CK_SP800_108_ITERATION_VARIABLE,
192-
pValue: counter_format as *const _ as *mut _,
193-
ulValueLen: size_of::<cryptoki_sys::CK_SP800_108_COUNTER_FORMAT>()
194-
as cryptoki_sys::CK_ULONG,
195-
}
196-
}
197-
PrfCounterDataParamType::DkmLength(dkm_length_format) => {
198-
cryptoki_sys::CK_PRF_DATA_PARAM {
199-
type_: cryptoki_sys::CK_SP800_108_DKM_LENGTH,
200-
pValue: dkm_length_format as *const _ as *mut _,
201-
ulValueLen: size_of::<cryptoki_sys::CK_SP800_108_DKM_LENGTH_FORMAT>()
202-
as cryptoki_sys::CK_ULONG,
203-
}
204-
}
205-
PrfCounterDataParamType::ByteArray(data) => cryptoki_sys::CK_PRF_DATA_PARAM {
206-
type_: cryptoki_sys::CK_SP800_108_BYTE_ARRAY,
207-
pValue: data.as_ptr() as *mut _,
208-
ulValueLen: data
209-
.len()
210-
.try_into()
211-
.expect("length of data parameter does not fit in CK_ULONG"),
212-
},
213-
},
214-
_marker: PhantomData,
215-
}
216-
}
217-
}
218-
219166
/// Container for information on an additional key to be derived.
220167
#[derive(Debug)]
221168
pub struct DerivedKey {
@@ -258,7 +205,7 @@ impl From<&mut DerivedKey> for cryptoki_sys::CK_DERIVED_KEY {
258205
///
259206
/// This structure wraps a `CK_SP800_108_KDF_PARAMS` structure.
260207
#[derive(Debug)]
261-
pub struct KbkdfCounterParams<'a> {
208+
pub struct KbkdfParams<'a> {
262209
/// Holds own data so that we have a contiguous memory region to give to backend
263210
additional_derived_keys: Option<Pin<Box<[cryptoki_sys::CK_DERIVED_KEY]>>>,
264211

@@ -267,7 +214,7 @@ pub struct KbkdfCounterParams<'a> {
267214
_marker: PhantomData<&'a [u8]>,
268215
}
269216

270-
impl<'a> KbkdfCounterParams<'a> {
217+
impl<'a> KbkdfParams<'a> {
271218
/// Construct parameters for NIST SP 800-108 KDF (aka KBKDF) pseuderandom function-based key
272219
/// derivation function, in counter-mode.
273220
///
@@ -280,7 +227,7 @@ impl<'a> KbkdfCounterParams<'a> {
280227
/// * `additional_derived_keys` - Any additional keys to be generated by the KDF from the base key.
281228
pub fn new(
282229
prf_mechanism: MechanismType,
283-
prf_data_params: &'a [PrfCounterDataParam<'a>],
230+
prf_data_params: &'a [PrfDataParam<'a>],
284231
additional_derived_keys: Option<&'a mut [DerivedKey]>,
285232
) -> Self {
286233
let mut additional_derived_keys = additional_derived_keys
@@ -424,84 +371,3 @@ impl<'a> KbkdfFeedbackParams<'a> {
424371
})
425372
}
426373
}
427-
428-
/// NIST SP 800-108 (aka KBKDF) double pipeline-mode parameters.
429-
///
430-
/// This structure wraps a `CK_SP800_108_KDF_PARAMS` structure.
431-
#[derive(Debug)]
432-
pub struct KbkdfDoublePipelineParams<'a> {
433-
/// Holds own data so that we have a contiguous memory region to give to backend
434-
additional_derived_keys: Option<Pin<Box<[cryptoki_sys::CK_DERIVED_KEY]>>>,
435-
436-
inner: cryptoki_sys::CK_SP800_108_KDF_PARAMS,
437-
/// Marker type to ensure we don't outlive the data
438-
_marker: PhantomData<&'a [u8]>,
439-
}
440-
441-
impl<'a> KbkdfDoublePipelineParams<'a> {
442-
/// Construct parameters for NIST SP 800-108 KDF (aka KBKDF) pseuderandom function-based key
443-
/// derivation function, in double pipeline-mode.
444-
///
445-
/// # Arguments
446-
///
447-
/// * `prf_mechanism` - The pseudorandom function that underlies the KBKDF operation.
448-
///
449-
/// * `prf_data_params` - The sequence of data segments used as input data for the PRF. Requires at least [`PrfDataParam::IterationVariable`].
450-
///
451-
/// * `additional_derived_keys` - Any additional keys to be generated by the KDF from the base key.
452-
pub fn new(
453-
prf_mechanism: MechanismType,
454-
prf_data_params: &'a [PrfDataParam<'a>],
455-
additional_derived_keys: Option<&'a mut [DerivedKey]>,
456-
) -> Self {
457-
let mut additional_derived_keys = additional_derived_keys
458-
.map(|keys| {
459-
keys.iter_mut()
460-
.map(Into::into)
461-
.collect::<Box<[cryptoki_sys::CK_DERIVED_KEY]>>()
462-
})
463-
.map(Pin::new);
464-
465-
let inner = cryptoki_sys::CK_SP800_108_KDF_PARAMS {
466-
prfType: prf_mechanism.into(),
467-
ulNumberOfDataParams: prf_data_params
468-
.len()
469-
.try_into()
470-
.expect("number of data parameters does not fit in CK_ULONG"),
471-
pDataParams: prf_data_params.as_ptr() as cryptoki_sys::CK_PRF_DATA_PARAM_PTR,
472-
ulAdditionalDerivedKeys: additional_derived_keys.as_ref().map_or(0, |keys| {
473-
keys.len()
474-
.try_into()
475-
.expect("number of additional derived keys does not fit in CK_ULONG")
476-
}),
477-
pAdditionalDerivedKeys: additional_derived_keys
478-
.as_mut()
479-
.map_or(ptr::null_mut(), |keys| {
480-
keys.as_mut_ptr() as cryptoki_sys::CK_DERIVED_KEY_PTR
481-
}),
482-
};
483-
484-
Self {
485-
additional_derived_keys,
486-
487-
inner,
488-
_marker: PhantomData,
489-
}
490-
}
491-
492-
pub(crate) fn inner(&self) -> &cryptoki_sys::CK_SP800_108_KDF_PARAMS {
493-
&self.inner
494-
}
495-
496-
/// The additional keys derived by the KDF, as per the params
497-
pub(crate) fn additional_derived_keys(&self) -> Option<Vec<ObjectHandle>> {
498-
self.additional_derived_keys.as_ref().map(|keys| {
499-
keys.iter()
500-
.map(|key| {
501-
// SAFETY: a value is always provided during construction
502-
ObjectHandle::new(unsafe { *key.phKey })
503-
})
504-
.collect()
505-
})
506-
}
507-
}

cryptoki/src/mechanism/mod.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1000,11 +1000,11 @@ pub enum Mechanism<'a> {
10001000

10011001
// NIST SP 800-108 KDF (aka KBKDF)
10021002
/// NIST SP 800-108 KDF (aka KBKDF) mechanism in counter-mode
1003-
KbkdfCounter(kbkdf::KbkdfCounterParams<'a>),
1003+
KbkdfCounter(kbkdf::KbkdfParams<'a>),
10041004
/// NIST SP 800-108 KDF (aka KBKDF) mechanism in feedback-mode
10051005
KbkdfFeedback(kbkdf::KbkdfFeedbackParams<'a>),
10061006
/// NIST SP 800-108 KDF (aka KBKDF) mechanism in double pipeline-mode
1007-
KbkdfDoublePipeline(kbkdf::KbkdfDoublePipelineParams<'a>),
1007+
KbkdfDoublePipeline(kbkdf::KbkdfParams<'a>),
10081008

10091009
/// Vendor defined mechanism
10101010
VendorDefined(VendorDefinedMechanism<'a>),
@@ -1137,9 +1137,10 @@ impl From<&Mechanism<'_>> for CK_MECHANISM {
11371137
Mechanism::HkdfDerive(params) | Mechanism::HkdfData(params) => {
11381138
make_mechanism(mechanism, params)
11391139
}
1140-
Mechanism::KbkdfCounter(params) => make_mechanism(mechanism, params.inner()),
1140+
Mechanism::KbkdfCounter(params) | Mechanism::KbkdfDoublePipeline(params) => {
1141+
make_mechanism(mechanism, params.inner())
1142+
}
11411143
Mechanism::KbkdfFeedback(params) => make_mechanism(mechanism, params.inner()),
1142-
Mechanism::KbkdfDoublePipeline(params) => make_mechanism(mechanism, params.inner()),
11431144
// Mechanisms without parameters
11441145
Mechanism::AesKeyGen
11451146
| Mechanism::AesEcb

0 commit comments

Comments
 (0)