Skip to content

Commit 8d4fca9

Browse files
committed
feat: revise EdDSA mechanism to support optional params
This revises the `Mechanism::Eddsa` struct to receive a `EddsaParams` struct as an optional argument. Signed-off-by: Mete Can Eriş <[email protected]>
1 parent 4cb53df commit 8d4fca9

File tree

3 files changed

+130
-8
lines changed

3 files changed

+130
-8
lines changed

cryptoki/src/mechanism/eddsa.rs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
//! EdDSA mechanism types
2+
3+
use cryptoki_sys::*;
4+
use std::marker::PhantomData;
5+
6+
/// EdDSA parameters.
7+
///
8+
/// The EdDSA mechanism, denoted CKM_EDDSA, is a mechanism for
9+
/// single-part and multipart signatures and verification for
10+
/// EdDSA. This mechanism implements the five EdDSA signature
11+
/// schemes defined in RFC 8032 and RFC 8410.
12+
///
13+
/// For curves according to RFC 8032, this mechanism has an
14+
/// optional parameter, a CK_EDDSA_PARAMS structure.
15+
///
16+
/// The absence or presence of the parameter as well as its
17+
/// content is used to identify which signature scheme is to be
18+
/// used.
19+
///
20+
/// | Signature Scheme | Mechanism Param | phFlag | Context Data |
21+
/// |------------------|-----------------|--------|--------------|
22+
/// | Ed25519 | Not Required | N/A | N/A |
23+
/// | Ed25519ctx | Required | False | Optional |
24+
/// | Ed25519ph | Required | True | Optional |
25+
/// | Ed448 | Required | False | Optional |
26+
/// | Ed448ph | Required | True | Optional |
27+
///
28+
/// This structure wraps a `CK_EDDSA_PARAMS` structure.
29+
#[derive(Copy, Debug, Clone)]
30+
#[repr(transparent)]
31+
pub struct EddsaParams<'a> {
32+
inner: CK_EDDSA_PARAMS,
33+
_marker: PhantomData<&'a [u8]>,
34+
}
35+
36+
impl EddsaParams<'_> {
37+
/// Construct EdDSA parameters.
38+
///
39+
/// # Arguments
40+
///
41+
/// * `params` - The CK_EDDSA_PARAMS structure.
42+
pub fn new(params: CK_EDDSA_PARAMS) -> Self {
43+
Self {
44+
inner: params,
45+
_marker: PhantomData,
46+
}
47+
}
48+
}
49+
50+
impl Default for EddsaParams<'_> {
51+
/// Provide a default instance of `EddsaParams`.
52+
///
53+
/// This initializes `EddsaParams` with the default value
54+
/// of the `CK_EDDSA_PARAMS` structure.
55+
fn default() -> Self {
56+
Self {
57+
inner: CK_EDDSA_PARAMS::default(),
58+
_marker: PhantomData,
59+
}
60+
}
61+
}

cryptoki/src/mechanism/mod.rs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
//! Data types for mechanisms
44
55
pub mod aead;
6+
pub mod eddsa;
67
pub mod ekdf;
78
pub mod elliptic_curve;
89
pub mod hkdf;
@@ -902,11 +903,16 @@ pub enum Mechanism<'a> {
902903
EcdsaSha512,
903904
/// EDDSA mechanism
904905
///
906+
/// This mechanism has an optional parameter, a CK_EDDSA_PARAMS
907+
/// structure. The absence or presence of the parameter as well
908+
/// as its content is used to identify which signature scheme
909+
/// is to be used.
910+
///
905911
/// Note: EdDSA is not part of the PKCS#11 v2.40 standard and as
906-
/// such may not be understood by the backend. It is included here
907-
/// because some vendor implementations support it through the
908-
/// v2.40 interface.
909-
Eddsa,
912+
/// such may not be understood by some backends. It is included
913+
/// here because some vendor implementations support it through
914+
/// the v2.40 interface.
915+
Eddsa(Option<eddsa::EddsaParams<'a>>),
910916

911917
// SHA-n
912918
/// SHA-1 mechanism
@@ -1001,7 +1007,7 @@ impl Mechanism<'_> {
10011007
Mechanism::EccKeyPairGen => MechanismType::ECC_KEY_PAIR_GEN,
10021008
Mechanism::EccEdwardsKeyPairGen => MechanismType::ECC_EDWARDS_KEY_PAIR_GEN,
10031009
Mechanism::EccMontgomeryKeyPairGen => MechanismType::ECC_MONTGOMERY_KEY_PAIR_GEN,
1004-
Mechanism::Eddsa => MechanismType::EDDSA,
1010+
Mechanism::Eddsa(_) => MechanismType::EDDSA,
10051011
Mechanism::Ecdh1Derive(_) => MechanismType::ECDH1_DERIVE,
10061012
Mechanism::Ecdsa => MechanismType::ECDSA,
10071013
Mechanism::EcdsaSha1 => MechanismType::ECDSA_SHA1,
@@ -1073,6 +1079,13 @@ impl From<&Mechanism<'_>> for CK_MECHANISM {
10731079
| Mechanism::Sha512RsaPkcsPss(params) => make_mechanism(mechanism, params),
10741080
Mechanism::RsaPkcsOaep(params) => make_mechanism(mechanism, params),
10751081
Mechanism::Ecdh1Derive(params) => make_mechanism(mechanism, params),
1082+
Mechanism::Eddsa(params) => match params {
1083+
Some(params) => make_mechanism(mechanism, params),
1084+
None => CK_MECHANISM {
1085+
mechanism,
1086+
..Default::default()
1087+
},
1088+
},
10761089
Mechanism::HkdfDerive(params) | Mechanism::HkdfData(params) => {
10771090
make_mechanism(mechanism, params)
10781091
}
@@ -1098,7 +1111,6 @@ impl From<&Mechanism<'_>> for CK_MECHANISM {
10981111
| Mechanism::EccKeyPairGen
10991112
| Mechanism::EccEdwardsKeyPairGen
11001113
| Mechanism::EccMontgomeryKeyPairGen
1101-
| Mechanism::Eddsa
11021114
| Mechanism::Ecdsa
11031115
| Mechanism::EcdsaSha1
11041116
| Mechanism::EcdsaSha224

cryptoki/tests/basic.rs

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use common::init_pins;
77
use cryptoki::context::Function;
88
use cryptoki::error::{Error, RvError};
99
use cryptoki::mechanism::aead::GcmParams;
10+
use cryptoki::mechanism::eddsa::EddsaParams;
1011
use cryptoki::mechanism::rsa::{PkcsMgfType, PkcsOaepParams, PkcsOaepSource};
1112
use cryptoki::mechanism::{Mechanism, MechanismType};
1213
use cryptoki::object::{
@@ -99,9 +100,57 @@ fn sign_verify_ed25519() -> TestResult {
99100

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

102-
let signature = session.sign(&Mechanism::Eddsa, private, &data)?;
103+
let signature = session.sign(&Mechanism::Eddsa(None), private, &data)?;
103104

104-
session.verify(&Mechanism::Eddsa, public, &data, &signature)?;
105+
session.verify(&Mechanism::Eddsa(None), public, &data, &signature)?;
106+
107+
session.destroy_object(public)?;
108+
session.destroy_object(private)?;
109+
110+
Ok(())
111+
}
112+
113+
#[test]
114+
#[serial]
115+
fn sign_verify_ed25519_with_eddsa_params() -> TestResult {
116+
let (pkcs11, slot) = init_pins();
117+
118+
let session = pkcs11.open_rw_session(slot)?;
119+
120+
session.login(UserType::User, Some(&AuthPin::new(USER_PIN.into())))?;
121+
122+
let mechanism = Mechanism::EccEdwardsKeyPairGen;
123+
124+
let pub_key_template = vec![
125+
Attribute::Token(true),
126+
Attribute::Private(false),
127+
Attribute::Verify(true),
128+
// Ed25519 OID
129+
// See: https://github.com/opendnssec/SoftHSMv2/blob/ac70dc398b236e4522101930e790008936489e2d/src/lib/test/SignVerifyTests.cpp#L173
130+
Attribute::EcParams(vec![
131+
0x13, 0x0c, 0x65, 0x64, 0x77, 0x61, 0x72, 0x64, 0x73, 0x32, 0x35, 0x35, 0x31, 0x39,
132+
]),
133+
];
134+
135+
let priv_key_template = vec![Attribute::Token(true)];
136+
137+
let (public, private) =
138+
session.generate_key_pair(&mechanism, &pub_key_template, &priv_key_template)?;
139+
140+
let data = [0xFF, 0x55, 0xDD];
141+
142+
let signature = session.sign(
143+
&Mechanism::Eddsa(Some(EddsaParams::default())),
144+
private,
145+
&data,
146+
)?;
147+
148+
session.verify(
149+
&Mechanism::Eddsa(Some(EddsaParams::default())),
150+
public,
151+
&data,
152+
&signature,
153+
)?;
105154

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

0 commit comments

Comments
 (0)