Skip to content

Commit

Permalink
Added CKM_AES_CBC_ENCRYPT_DATA;
Browse files Browse the repository at this point in the history
Added CKM_GENERIC_SECRET_KEY_GEN;
Added prettier `MechanismInfo` fmt.

Signed-off-by: nikita.kalinichenko <[email protected]>
  • Loading branch information
Nk185 committed Oct 10, 2023
1 parent 16e6d15 commit 8934682
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 14 deletions.
55 changes: 55 additions & 0 deletions cryptoki/src/mechanism/ekdf.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Copyright 2021 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
//! Mechanisms of key derivation by data encryption
//! See: https://docs.oasis-open.org/pkcs11/pkcs11-spec/v3.1/os/pkcs11-spec-v3.1-os.html#_Toc111203514

use std::{convert::TryInto, marker::PhantomData, slice};

/// AES CBC derivation parameters.
///
/// The mechanisms will function by performing the encryption over the data provided using the base
/// key. The resulting cipher text shall be used to create the key value of the resulting key.
///
/// This structure wraps a `CK_AES_CBC_ENCRYPT_DATA_PARAMS` structure.
#[derive(Debug, Clone, Copy)]
#[repr(transparent)]
pub struct AesCbcDeriveParams<'a> {
inner: cryptoki_sys::CK_AES_CBC_ENCRYPT_DATA_PARAMS,

/// Marker type to ensure we don't outlive the data
_marker: PhantomData<&'a [u8]>,
}

impl<'a> AesCbcDeriveParams<'a> {
/// Construct parameters for key derivation via encryption (EKDF).
///
/// # Arguments
///
/// * `iv` - The initialization vector
///
/// * `data` - Data that will be encryption with the base key to obtain
/// the new key from the resulted cypher.
pub fn new(iv: [u8; 16], data: &'a [u8]) -> Self {
Self {
inner: cryptoki_sys::CK_AES_CBC_ENCRYPT_DATA_PARAMS {
iv,
pData: data.as_ptr() as *mut _,
length: data
.len()
.try_into()
.expect("data length does not fit in CK_ULONG"),
},
_marker: PhantomData,
}
}

/// The initialization vector.
pub fn iv(&self) -> &'a [u8] {
unsafe { slice::from_raw_parts(self.inner.iv.as_ptr(), self.inner.iv.len()) }
}

/// The data.
pub fn data(&self) -> &'a [u8] {
unsafe { slice::from_raw_parts(self.inner.pData, self.inner.length as _) }
}
}
19 changes: 18 additions & 1 deletion cryptoki/src/mechanism/mechanism_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

use bitflags::bitflags;
use cryptoki_sys::*;
use std::fmt::Debug;
use std::fmt::{Debug, Formatter};

bitflags! {
struct MechanismInfoFlags: CK_FLAGS {
Expand Down Expand Up @@ -219,6 +219,23 @@ impl MechanismInfo {
}
}

impl std::fmt::Display for MechanismInfo {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let flags = format!("{0:#?}", self.flags);
let key_size_info = match self.min_key_size == 0 && self.max_key_size == 0 {
true => String::new(),
false => {
if self.max_key_size == 0 {
format!(", min_key_size={}", self.min_key_size)
} else {
format!(", min_key_size={}, max_key_size={}", self.min_key_size, self.max_key_size)
}
}
};
write!(f, "{}{}", flags, key_size_info)
}
}

#[doc(hidden)]
impl From<CK_MECHANISM_INFO> for MechanismInfo {
fn from(val: CK_MECHANISM_INFO) -> Self {
Expand Down
53 changes: 40 additions & 13 deletions cryptoki/src/mechanism/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ pub mod aead;
pub mod elliptic_curve;
mod mechanism_info;
pub mod rsa;
pub mod ekdf;

use crate::error::Error;
use cryptoki_sys::*;
Expand All @@ -17,6 +18,7 @@ use std::ops::Deref;
use std::ptr::null_mut;

pub use mechanism_info::MechanismInfo;
use crate::mechanism::rsa::{PkcsOaepParams, PkcsOaepSource};

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

/// Derivation via encryption
pub const AES_CBC_ENCRYPT_DATA: MechanismType = MechanismType { val: CKM_AES_CBC_ENCRYPT_DATA };

// RSA
/// PKCS #1 RSA key pair generation mechanism
pub const RSA_PKCS_KEY_PAIR_GEN: MechanismType = MechanismType {
Expand Down Expand Up @@ -241,6 +246,10 @@ impl MechanismType {
pub const SHA512_RSA_PKCS_PSS: MechanismType = MechanismType {
val: CKM_SHA512_RSA_PKCS_PSS,
};
/// GENERIC-SECRET-KEY-GEN mechanism
pub const GENERIC_SECRET_KEY_GEN: MechanismType = MechanismType{
val: CKM_GENERIC_SECRET_KEY_GEN
};

pub(crate) fn stringify(mech: CK_MECHANISM_TYPE) -> String {
match mech {
Expand Down Expand Up @@ -629,6 +638,7 @@ impl TryFrom<CK_MECHANISM_TYPE> for MechanismType {
fn try_from(mechanism_type: CK_MECHANISM_TYPE) -> Result<Self, Self::Error> {
match mechanism_type {
CKM_AES_KEY_GEN => Ok(MechanismType::AES_KEY_GEN),
CKM_AES_CBC_ENCRYPT_DATA => Ok(MechanismType::AES_CBC_ENCRYPT_DATA),
CKM_RSA_PKCS_KEY_PAIR_GEN => Ok(MechanismType::RSA_PKCS_KEY_PAIR_GEN),
CKM_RSA_PKCS => Ok(MechanismType::RSA_PKCS),
CKM_RSA_PKCS_PSS => Ok(MechanismType::RSA_PKCS_PSS),
Expand All @@ -648,6 +658,7 @@ impl TryFrom<CK_MECHANISM_TYPE> for MechanismType {
CKM_SHA256_RSA_PKCS => Ok(MechanismType::SHA256_RSA_PKCS),
CKM_SHA384_RSA_PKCS => Ok(MechanismType::SHA384_RSA_PKCS),
CKM_SHA512_RSA_PKCS => Ok(MechanismType::SHA512_RSA_PKCS),
CKM_GENERIC_SECRET_KEY_GEN => Ok(MechanismType::GENERIC_SECRET_KEY_GEN),
other => {
error!("Mechanism type {} is not supported.", other);
Err(Error::NotSupported)
Expand Down Expand Up @@ -689,6 +700,14 @@ pub enum Mechanism<'a> {
AesKeyWrapPad,
/// AES-GCM mechanism
AesGcm(aead::GcmParams<'a>),
/// AES-CBC-ENCRYPT-DATA mechanism
///
/// The parameter to this mechanism is the initialization vector and the message to encrypt. These mechanisms allow
/// derivation of keys using the result of an encryption operation as the key value.
///
/// For derivation, the message length must be a multiple of the block
/// size. See https://www.cryptsoft.com/pkcs11doc/v220/
AesCbcEncryptData(ekdf::AesCbcDeriveParams<'a>),

// RSA
/// PKCS #1 RSA key pair generation mechanism
Expand All @@ -701,7 +720,7 @@ pub enum Mechanism<'a> {
RsaPkcsPss(rsa::PkcsPssParams),
/// Multi-purpose mechanism based on the RSA public-key cryptosystem and the OAEP block format
/// defined in PKCS #1
RsaPkcsOaep(rsa::PkcsOaepParams<'a>),
RsaPkcsOaep(PkcsOaepParams<'a>),
/// Multi-purpose mechanism based on the RSA public-key cryptosystem. This is so-called "raw"
/// RSA, as assumed in X.509.
RsaX509,
Expand Down Expand Up @@ -816,6 +835,9 @@ pub enum Mechanism<'a> {
Sha384RsaPkcsPss(rsa::PkcsPssParams),
/// SHA256-RSA-PKCS-PSS mechanism
Sha512RsaPkcsPss(rsa::PkcsPssParams),

/// GENERIC-SECRET-KEY-GEN mechanism
GenericSecretKeyGen
}

impl Mechanism<'_> {
Expand All @@ -829,7 +851,7 @@ impl Mechanism<'_> {
Mechanism::AesKeyWrap => MechanismType::AES_KEY_WRAP,
Mechanism::AesKeyWrapPad => MechanismType::AES_KEY_WRAP_PAD,
Mechanism::AesGcm(_) => MechanismType::AES_GCM,

Mechanism::AesCbcEncryptData(_) =>MechanismType::AES_CBC_ENCRYPT_DATA,
Mechanism::RsaPkcsKeyPairGen => MechanismType::RSA_PKCS_KEY_PAIR_GEN,
Mechanism::RsaPkcs => MechanismType::RSA_PKCS,
Mechanism::RsaPkcsPss(_) => MechanismType::RSA_PKCS_PSS,
Expand Down Expand Up @@ -874,6 +896,8 @@ impl Mechanism<'_> {
Mechanism::Sha256RsaPkcsPss(_) => MechanismType::SHA256_RSA_PKCS_PSS,
Mechanism::Sha384RsaPkcsPss(_) => MechanismType::SHA384_RSA_PKCS_PSS,
Mechanism::Sha512RsaPkcsPss(_) => MechanismType::SHA512_RSA_PKCS_PSS,

Mechanism::GenericSecretKeyGen => MechanismType::GENERIC_SECRET_KEY_GEN
}
}
}
Expand All @@ -883,9 +907,13 @@ impl From<&Mechanism<'_>> for CK_MECHANISM {
let mechanism = mech.mechanism_type().into();
match mech {
// Mechanisms with parameters
Mechanism::AesCbc(params) | Mechanism::AesCbcPad(params) => {
Mechanism::AesCbc(params)
| Mechanism::AesCbcPad(params) => {
make_mechanism(mechanism, params)
}
},
Mechanism::AesCbcEncryptData(params) => {
make_mechanism(mechanism, params)
},
Mechanism::DesCbc(params)
| Mechanism::Des3Cbc(params)
| Mechanism::DesCbcPad(params)
Expand Down Expand Up @@ -936,7 +964,8 @@ impl From<&Mechanism<'_>> for CK_MECHANISM {
| Mechanism::Sha224RsaPkcs
| Mechanism::Sha256RsaPkcs
| Mechanism::Sha384RsaPkcs
| Mechanism::Sha512RsaPkcs => CK_MECHANISM {
| Mechanism::Sha512RsaPkcs
| Mechanism::GenericSecretKeyGen => CK_MECHANISM {
mechanism,
pParameter: null_mut(),
ulParameterLen: 0,
Expand All @@ -961,7 +990,7 @@ fn make_mechanism<T>(mechanism: CK_MECHANISM_TYPE, param: &T) -> CK_MECHANISM {

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

fn try_from(alg: psa_crypto::types::algorithm::Algorithm) -> Result<Self, Self::Error> {
Expand Down Expand Up @@ -989,13 +1018,11 @@ impl TryFrom<psa_crypto::types::algorithm::Algorithm> for Mechanism {
Ok(Mechanism::Ecdsa)
}
Algorithm::AsymmetricEncryption(AsymmetricEncryption::RsaOaep { hash_alg }) => {
Ok(Mechanism::RsaPkcsOaep(rsa::PkcsOaepParams {
hash_alg: Mechanism::try_from(Algorithm::from(hash_alg))?.mechanism_type(),
mgf: rsa::PkcsMgfType::from_psa_crypto_hash(hash_alg)?,
source: rsa::PkcsOaepSourceType::DATA_SPECIFIED,
source_data: std::ptr::null(),
source_data_len: 0.into(),
}))
Ok(Mechanism::RsaPkcsOaep(PkcsOaepParams::new(
Mechanism::try_from(Algorithm::from(hash_alg))?.mechanism_type(),
rsa::PkcsMgfType::from_psa_crypto_hash(hash_alg)?,
PkcsOaepSource::empty(),
)))
}
alg => {
error!("{:?} is not a supported algorithm", alg);
Expand Down

0 comments on commit 8934682

Please sign in to comment.