Skip to content

Commit 87ae885

Browse files
Nk185ionut-arm
authored andcommitted
Added CKM_AES_CBC_ENCRYPT_DATA;
Added CKM_GENERIC_SECRET_KEY_GEN; Added prettier `MechanismInfo` fmt. Signed-off-by: nikita.kalinichenko <thenik185@gmail.com>
1 parent c8af433 commit 87ae885

File tree

3 files changed

+113
-14
lines changed

3 files changed

+113
-14
lines changed

cryptoki/src/mechanism/ekdf.rs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Copyright 2021 Contributors to the Parsec project.
2+
// SPDX-License-Identifier: Apache-2.0
3+
//! Mechanisms of key derivation by data encryption
4+
//! See: https://docs.oasis-open.org/pkcs11/pkcs11-spec/v3.1/os/pkcs11-spec-v3.1-os.html#_Toc111203514
5+
6+
use std::{convert::TryInto, marker::PhantomData, slice};
7+
8+
/// AES CBC derivation parameters.
9+
///
10+
/// The mechanisms will function by performing the encryption over the data provided using the base
11+
/// key. The resulting cipher text shall be used to create the key value of the resulting key.
12+
///
13+
/// This structure wraps a `CK_AES_CBC_ENCRYPT_DATA_PARAMS` structure.
14+
#[derive(Debug, Clone, Copy)]
15+
#[repr(transparent)]
16+
pub struct AesCbcDeriveParams<'a> {
17+
inner: cryptoki_sys::CK_AES_CBC_ENCRYPT_DATA_PARAMS,
18+
19+
/// Marker type to ensure we don't outlive the data
20+
_marker: PhantomData<&'a [u8]>,
21+
}
22+
23+
impl<'a> AesCbcDeriveParams<'a> {
24+
/// Construct parameters for key derivation via encryption (EKDF).
25+
///
26+
/// # Arguments
27+
///
28+
/// * `iv` - The initialization vector
29+
///
30+
/// * `data` - Data that will be encryption with the base key to obtain
31+
/// the new key from the resulted cypher.
32+
pub fn new(iv: [u8; 16], data: &'a [u8]) -> Self {
33+
Self {
34+
inner: cryptoki_sys::CK_AES_CBC_ENCRYPT_DATA_PARAMS {
35+
iv,
36+
pData: data.as_ptr() as *mut _,
37+
length: data
38+
.len()
39+
.try_into()
40+
.expect("data length does not fit in CK_ULONG"),
41+
},
42+
_marker: PhantomData,
43+
}
44+
}
45+
46+
/// The initialization vector.
47+
pub fn iv(&self) -> &'a [u8] {
48+
unsafe { slice::from_raw_parts(self.inner.iv.as_ptr(), self.inner.iv.len()) }
49+
}
50+
51+
/// The data.
52+
pub fn data(&self) -> &'a [u8] {
53+
unsafe { slice::from_raw_parts(self.inner.pData, self.inner.length as _) }
54+
}
55+
}

cryptoki/src/mechanism/mechanism_info.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
55
use bitflags::bitflags;
66
use cryptoki_sys::*;
7-
use std::fmt::Debug;
7+
use std::fmt::{Debug, Formatter};
88

99
bitflags! {
1010
struct MechanismInfoFlags: CK_FLAGS {
@@ -219,6 +219,23 @@ impl MechanismInfo {
219219
}
220220
}
221221

222+
impl std::fmt::Display for MechanismInfo {
223+
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
224+
let flags = format!("{0:#?}", self.flags);
225+
let key_size_info = match self.min_key_size == 0 && self.max_key_size == 0 {
226+
true => String::new(),
227+
false => {
228+
if self.max_key_size == 0 {
229+
format!(", min_key_size={}", self.min_key_size)
230+
} else {
231+
format!(", min_key_size={}, max_key_size={}", self.min_key_size, self.max_key_size)
232+
}
233+
}
234+
};
235+
write!(f, "{}{}", flags, key_size_info)
236+
}
237+
}
238+
222239
#[doc(hidden)]
223240
impl From<CK_MECHANISM_INFO> for MechanismInfo {
224241
fn from(val: CK_MECHANISM_INFO) -> Self {

cryptoki/src/mechanism/mod.rs

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ pub mod aead;
66
pub mod elliptic_curve;
77
mod mechanism_info;
88
pub mod rsa;
9+
pub mod ekdf;
910

1011
use crate::error::Error;
1112
use cryptoki_sys::*;
@@ -17,6 +18,7 @@ use std::ops::Deref;
1718
use std::ptr::null_mut;
1819

1920
pub use mechanism_info::MechanismInfo;
21+
use crate::mechanism::rsa::{PkcsOaepParams, PkcsOaepSource};
2022

2123
#[derive(Copy, Debug, Clone, PartialEq, Eq)]
2224
// transparent so that a vector of MechanismType should have the same layout than a vector of
@@ -64,6 +66,9 @@ impl MechanismType {
6466
/// AES-GCM mechanism
6567
pub const AES_GCM: MechanismType = MechanismType { val: CKM_AES_GCM };
6668

69+
/// Derivation via encryption
70+
pub const AES_CBC_ENCRYPT_DATA: MechanismType = MechanismType { val: CKM_AES_CBC_ENCRYPT_DATA };
71+
6772
// RSA
6873
/// PKCS #1 RSA key pair generation mechanism
6974
pub const RSA_PKCS_KEY_PAIR_GEN: MechanismType = MechanismType {
@@ -241,6 +246,10 @@ impl MechanismType {
241246
pub const SHA512_RSA_PKCS_PSS: MechanismType = MechanismType {
242247
val: CKM_SHA512_RSA_PKCS_PSS,
243248
};
249+
/// GENERIC-SECRET-KEY-GEN mechanism
250+
pub const GENERIC_SECRET_KEY_GEN: MechanismType = MechanismType{
251+
val: CKM_GENERIC_SECRET_KEY_GEN
252+
};
244253

245254
pub(crate) fn stringify(mech: CK_MECHANISM_TYPE) -> String {
246255
match mech {
@@ -629,6 +638,7 @@ impl TryFrom<CK_MECHANISM_TYPE> for MechanismType {
629638
fn try_from(mechanism_type: CK_MECHANISM_TYPE) -> Result<Self, Self::Error> {
630639
match mechanism_type {
631640
CKM_AES_KEY_GEN => Ok(MechanismType::AES_KEY_GEN),
641+
CKM_AES_CBC_ENCRYPT_DATA => Ok(MechanismType::AES_CBC_ENCRYPT_DATA),
632642
CKM_RSA_PKCS_KEY_PAIR_GEN => Ok(MechanismType::RSA_PKCS_KEY_PAIR_GEN),
633643
CKM_RSA_PKCS => Ok(MechanismType::RSA_PKCS),
634644
CKM_RSA_PKCS_PSS => Ok(MechanismType::RSA_PKCS_PSS),
@@ -648,6 +658,7 @@ impl TryFrom<CK_MECHANISM_TYPE> for MechanismType {
648658
CKM_SHA256_RSA_PKCS => Ok(MechanismType::SHA256_RSA_PKCS),
649659
CKM_SHA384_RSA_PKCS => Ok(MechanismType::SHA384_RSA_PKCS),
650660
CKM_SHA512_RSA_PKCS => Ok(MechanismType::SHA512_RSA_PKCS),
661+
CKM_GENERIC_SECRET_KEY_GEN => Ok(MechanismType::GENERIC_SECRET_KEY_GEN),
651662
other => {
652663
error!("Mechanism type {} is not supported.", other);
653664
Err(Error::NotSupported)
@@ -689,6 +700,14 @@ pub enum Mechanism<'a> {
689700
AesKeyWrapPad,
690701
/// AES-GCM mechanism
691702
AesGcm(aead::GcmParams<'a>),
703+
/// AES-CBC-ENCRYPT-DATA mechanism
704+
///
705+
/// The parameter to this mechanism is the initialization vector and the message to encrypt. These mechanisms allow
706+
/// derivation of keys using the result of an encryption operation as the key value.
707+
///
708+
/// For derivation, the message length must be a multiple of the block
709+
/// size. See https://www.cryptsoft.com/pkcs11doc/v220/
710+
AesCbcEncryptData(ekdf::AesCbcDeriveParams<'a>),
692711

693712
// RSA
694713
/// PKCS #1 RSA key pair generation mechanism
@@ -701,7 +720,7 @@ pub enum Mechanism<'a> {
701720
RsaPkcsPss(rsa::PkcsPssParams),
702721
/// Multi-purpose mechanism based on the RSA public-key cryptosystem and the OAEP block format
703722
/// defined in PKCS #1
704-
RsaPkcsOaep(rsa::PkcsOaepParams<'a>),
723+
RsaPkcsOaep(PkcsOaepParams<'a>),
705724
/// Multi-purpose mechanism based on the RSA public-key cryptosystem. This is so-called "raw"
706725
/// RSA, as assumed in X.509.
707726
RsaX509,
@@ -816,6 +835,9 @@ pub enum Mechanism<'a> {
816835
Sha384RsaPkcsPss(rsa::PkcsPssParams),
817836
/// SHA256-RSA-PKCS-PSS mechanism
818837
Sha512RsaPkcsPss(rsa::PkcsPssParams),
838+
839+
/// GENERIC-SECRET-KEY-GEN mechanism
840+
GenericSecretKeyGen
819841
}
820842

821843
impl Mechanism<'_> {
@@ -829,7 +851,7 @@ impl Mechanism<'_> {
829851
Mechanism::AesKeyWrap => MechanismType::AES_KEY_WRAP,
830852
Mechanism::AesKeyWrapPad => MechanismType::AES_KEY_WRAP_PAD,
831853
Mechanism::AesGcm(_) => MechanismType::AES_GCM,
832-
854+
Mechanism::AesCbcEncryptData(_) =>MechanismType::AES_CBC_ENCRYPT_DATA,
833855
Mechanism::RsaPkcsKeyPairGen => MechanismType::RSA_PKCS_KEY_PAIR_GEN,
834856
Mechanism::RsaPkcs => MechanismType::RSA_PKCS,
835857
Mechanism::RsaPkcsPss(_) => MechanismType::RSA_PKCS_PSS,
@@ -874,6 +896,8 @@ impl Mechanism<'_> {
874896
Mechanism::Sha256RsaPkcsPss(_) => MechanismType::SHA256_RSA_PKCS_PSS,
875897
Mechanism::Sha384RsaPkcsPss(_) => MechanismType::SHA384_RSA_PKCS_PSS,
876898
Mechanism::Sha512RsaPkcsPss(_) => MechanismType::SHA512_RSA_PKCS_PSS,
899+
900+
Mechanism::GenericSecretKeyGen => MechanismType::GENERIC_SECRET_KEY_GEN
877901
}
878902
}
879903
}
@@ -883,9 +907,13 @@ impl From<&Mechanism<'_>> for CK_MECHANISM {
883907
let mechanism = mech.mechanism_type().into();
884908
match mech {
885909
// Mechanisms with parameters
886-
Mechanism::AesCbc(params) | Mechanism::AesCbcPad(params) => {
910+
Mechanism::AesCbc(params)
911+
| Mechanism::AesCbcPad(params) => {
887912
make_mechanism(mechanism, params)
888-
}
913+
},
914+
Mechanism::AesCbcEncryptData(params) => {
915+
make_mechanism(mechanism, params)
916+
},
889917
Mechanism::DesCbc(params)
890918
| Mechanism::Des3Cbc(params)
891919
| Mechanism::DesCbcPad(params)
@@ -936,7 +964,8 @@ impl From<&Mechanism<'_>> for CK_MECHANISM {
936964
| Mechanism::Sha224RsaPkcs
937965
| Mechanism::Sha256RsaPkcs
938966
| Mechanism::Sha384RsaPkcs
939-
| Mechanism::Sha512RsaPkcs => CK_MECHANISM {
967+
| Mechanism::Sha512RsaPkcs
968+
| Mechanism::GenericSecretKeyGen => CK_MECHANISM {
940969
mechanism,
941970
pParameter: null_mut(),
942971
ulParameterLen: 0,
@@ -961,7 +990,7 @@ fn make_mechanism<T>(mechanism: CK_MECHANISM_TYPE, param: &T) -> CK_MECHANISM {
961990

962991
#[cfg(feature = "psa-crypto-conversions")]
963992
#[allow(deprecated)]
964-
impl TryFrom<psa_crypto::types::algorithm::Algorithm> for Mechanism {
993+
impl TryFrom<psa_crypto::types::algorithm::Algorithm> for Mechanism<'_> {
965994
type Error = Error;
966995

967996
fn try_from(alg: psa_crypto::types::algorithm::Algorithm) -> Result<Self, Self::Error> {
@@ -989,13 +1018,11 @@ impl TryFrom<psa_crypto::types::algorithm::Algorithm> for Mechanism {
9891018
Ok(Mechanism::Ecdsa)
9901019
}
9911020
Algorithm::AsymmetricEncryption(AsymmetricEncryption::RsaOaep { hash_alg }) => {
992-
Ok(Mechanism::RsaPkcsOaep(rsa::PkcsOaepParams {
993-
hash_alg: Mechanism::try_from(Algorithm::from(hash_alg))?.mechanism_type(),
994-
mgf: rsa::PkcsMgfType::from_psa_crypto_hash(hash_alg)?,
995-
source: rsa::PkcsOaepSourceType::DATA_SPECIFIED,
996-
source_data: std::ptr::null(),
997-
source_data_len: 0.into(),
998-
}))
1021+
Ok(Mechanism::RsaPkcsOaep(PkcsOaepParams::new(
1022+
Mechanism::try_from(Algorithm::from(hash_alg))?.mechanism_type(),
1023+
rsa::PkcsMgfType::from_psa_crypto_hash(hash_alg)?,
1024+
PkcsOaepSource::empty(),
1025+
)))
9991026
}
10001027
alg => {
10011028
error!("{:?} is not a supported algorithm", alg);

0 commit comments

Comments
 (0)