Skip to content

Commit

Permalink
feat: revise EdDSA mechanism to support optional params
Browse files Browse the repository at this point in the history
This revises the `Mechanism::Eddsa` struct to receive a `EddsaParams` struct as an optional argument.

Signed-off-by: Mete Can Eriş <[email protected]>
  • Loading branch information
mcaneris committed Jan 18, 2025
1 parent 4cb53df commit 8d4fca9
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 8 deletions.
61 changes: 61 additions & 0 deletions cryptoki/src/mechanism/eddsa.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
//! EdDSA mechanism types
use cryptoki_sys::*;
use std::marker::PhantomData;

/// EdDSA parameters.
///
/// The EdDSA mechanism, denoted CKM_EDDSA, is a mechanism for
/// single-part and multipart signatures and verification for
/// EdDSA. This mechanism implements the five EdDSA signature
/// schemes defined in RFC 8032 and RFC 8410.
///
/// For curves according to RFC 8032, this mechanism has an
/// optional parameter, a CK_EDDSA_PARAMS structure.
///
/// The absence or presence of the parameter as well as its
/// content is used to identify which signature scheme is to be
/// used.
///
/// | Signature Scheme | Mechanism Param | phFlag | Context Data |
/// |------------------|-----------------|--------|--------------|
/// | Ed25519 | Not Required | N/A | N/A |
/// | Ed25519ctx | Required | False | Optional |
/// | Ed25519ph | Required | True | Optional |
/// | Ed448 | Required | False | Optional |
/// | Ed448ph | Required | True | Optional |
///
/// This structure wraps a `CK_EDDSA_PARAMS` structure.
#[derive(Copy, Debug, Clone)]
#[repr(transparent)]
pub struct EddsaParams<'a> {
inner: CK_EDDSA_PARAMS,
_marker: PhantomData<&'a [u8]>,
}

impl EddsaParams<'_> {
/// Construct EdDSA parameters.
///
/// # Arguments
///
/// * `params` - The CK_EDDSA_PARAMS structure.
pub fn new(params: CK_EDDSA_PARAMS) -> Self {
Self {
inner: params,
_marker: PhantomData,
}
}
}

impl Default for EddsaParams<'_> {
/// Provide a default instance of `EddsaParams`.
///
/// This initializes `EddsaParams` with the default value
/// of the `CK_EDDSA_PARAMS` structure.
fn default() -> Self {
Self {
inner: CK_EDDSA_PARAMS::default(),
_marker: PhantomData,
}
}
}
24 changes: 18 additions & 6 deletions cryptoki/src/mechanism/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
//! Data types for mechanisms
pub mod aead;
pub mod eddsa;
pub mod ekdf;
pub mod elliptic_curve;
pub mod hkdf;
Expand Down Expand Up @@ -902,11 +903,16 @@ pub enum Mechanism<'a> {
EcdsaSha512,
/// EDDSA mechanism
///
/// This mechanism has an optional parameter, a CK_EDDSA_PARAMS
/// structure. The absence or presence of the parameter as well
/// as its content is used to identify which signature scheme
/// is to be used.
///
/// Note: EdDSA is not part of the PKCS#11 v2.40 standard and as
/// such may not be understood by the backend. It is included here
/// because some vendor implementations support it through the
/// v2.40 interface.
Eddsa,
/// such may not be understood by some backends. It is included
/// here because some vendor implementations support it through
/// the v2.40 interface.
Eddsa(Option<eddsa::EddsaParams<'a>>),

// SHA-n
/// SHA-1 mechanism
Expand Down Expand Up @@ -1001,7 +1007,7 @@ impl Mechanism<'_> {
Mechanism::EccKeyPairGen => MechanismType::ECC_KEY_PAIR_GEN,
Mechanism::EccEdwardsKeyPairGen => MechanismType::ECC_EDWARDS_KEY_PAIR_GEN,
Mechanism::EccMontgomeryKeyPairGen => MechanismType::ECC_MONTGOMERY_KEY_PAIR_GEN,
Mechanism::Eddsa => MechanismType::EDDSA,
Mechanism::Eddsa(_) => MechanismType::EDDSA,
Mechanism::Ecdh1Derive(_) => MechanismType::ECDH1_DERIVE,
Mechanism::Ecdsa => MechanismType::ECDSA,
Mechanism::EcdsaSha1 => MechanismType::ECDSA_SHA1,
Expand Down Expand Up @@ -1073,6 +1079,13 @@ impl From<&Mechanism<'_>> for CK_MECHANISM {
| Mechanism::Sha512RsaPkcsPss(params) => make_mechanism(mechanism, params),
Mechanism::RsaPkcsOaep(params) => make_mechanism(mechanism, params),
Mechanism::Ecdh1Derive(params) => make_mechanism(mechanism, params),
Mechanism::Eddsa(params) => match params {
Some(params) => make_mechanism(mechanism, params),
None => CK_MECHANISM {
mechanism,
..Default::default()
},
},
Mechanism::HkdfDerive(params) | Mechanism::HkdfData(params) => {
make_mechanism(mechanism, params)
}
Expand All @@ -1098,7 +1111,6 @@ impl From<&Mechanism<'_>> for CK_MECHANISM {
| Mechanism::EccKeyPairGen
| Mechanism::EccEdwardsKeyPairGen
| Mechanism::EccMontgomeryKeyPairGen
| Mechanism::Eddsa
| Mechanism::Ecdsa
| Mechanism::EcdsaSha1
| Mechanism::EcdsaSha224
Expand Down
53 changes: 51 additions & 2 deletions cryptoki/tests/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use common::init_pins;
use cryptoki::context::Function;
use cryptoki::error::{Error, RvError};
use cryptoki::mechanism::aead::GcmParams;
use cryptoki::mechanism::eddsa::EddsaParams;
use cryptoki::mechanism::rsa::{PkcsMgfType, PkcsOaepParams, PkcsOaepSource};
use cryptoki::mechanism::{Mechanism, MechanismType};
use cryptoki::object::{
Expand Down Expand Up @@ -99,9 +100,57 @@ fn sign_verify_ed25519() -> TestResult {

let data = [0xFF, 0x55, 0xDD];

let signature = session.sign(&Mechanism::Eddsa, private, &data)?;
let signature = session.sign(&Mechanism::Eddsa(None), private, &data)?;

session.verify(&Mechanism::Eddsa, public, &data, &signature)?;
session.verify(&Mechanism::Eddsa(None), public, &data, &signature)?;

session.destroy_object(public)?;
session.destroy_object(private)?;

Ok(())
}

#[test]
#[serial]
fn sign_verify_ed25519_with_eddsa_params() -> TestResult {
let (pkcs11, slot) = init_pins();

let session = pkcs11.open_rw_session(slot)?;

session.login(UserType::User, Some(&AuthPin::new(USER_PIN.into())))?;

let mechanism = Mechanism::EccEdwardsKeyPairGen;

let pub_key_template = vec![
Attribute::Token(true),
Attribute::Private(false),
Attribute::Verify(true),
// Ed25519 OID
// See: https://github.com/opendnssec/SoftHSMv2/blob/ac70dc398b236e4522101930e790008936489e2d/src/lib/test/SignVerifyTests.cpp#L173
Attribute::EcParams(vec![
0x13, 0x0c, 0x65, 0x64, 0x77, 0x61, 0x72, 0x64, 0x73, 0x32, 0x35, 0x35, 0x31, 0x39,
]),
];

let priv_key_template = vec![Attribute::Token(true)];

let (public, private) =
session.generate_key_pair(&mechanism, &pub_key_template, &priv_key_template)?;

let data = [0xFF, 0x55, 0xDD];

let signature = session.sign(
&Mechanism::Eddsa(Some(EddsaParams::default())),
private,
&data,
)?;

session.verify(
&Mechanism::Eddsa(Some(EddsaParams::default())),
public,
&data,
&signature,
)?;

session.destroy_object(public)?;
session.destroy_object(private)?;
Expand Down

0 comments on commit 8d4fca9

Please sign in to comment.