Skip to content

Commit 8a7ff00

Browse files
swensonJakujeteythoon
committed
ML-KEM/ML-DSA part 4: ML-DSA
Splitting up #2405 into a few parts as suggest by @alex. Adapting ML-DSA changes from #2405 to use the OsslParamBuilder changes over the last few PRs and to juggle lifetimes appropriately Co-authored-by: Jakub Jelen <[email protected]> Co-authored-by: Justus Winter <[email protected]>
1 parent 24f9a7c commit 8a7ff00

File tree

4 files changed

+526
-0
lines changed

4 files changed

+526
-0
lines changed

openssl/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,12 +185,16 @@ pub mod pkcs5;
185185
pub mod pkcs7;
186186
pub mod pkey;
187187
pub mod pkey_ctx;
188+
#[cfg(ossl350)]
189+
pub mod pkey_ml_dsa;
188190
#[cfg(ossl300)]
189191
pub mod provider;
190192
pub mod rand;
191193
pub mod rsa;
192194
pub mod sha;
193195
pub mod sign;
196+
#[cfg(ossl300)]
197+
pub mod signature;
194198
pub mod srtp;
195199
pub mod ssl;
196200
pub mod stack;

openssl/src/pkey_ctx.rs

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ use crate::bn::BigNumRef;
6868
#[cfg(not(any(boringssl, awslc)))]
6969
use crate::cipher::CipherRef;
7070
use crate::error::ErrorStack;
71+
#[cfg(ossl300)]
72+
use crate::lib_ctx::LibCtxRef;
7173
use crate::md::MdRef;
7274
use crate::nid::Nid;
7375
use crate::pkey::{HasPrivate, HasPublic, Id, PKey, PKeyRef, Params, Private};
@@ -84,6 +86,8 @@ use openssl_macros::corresponds;
8486
use std::convert::TryFrom;
8587
#[cfg(ossl320)]
8688
use std::ffi::CStr;
89+
#[cfg(ossl300)]
90+
use std::ffi::CString;
8791
use std::ptr;
8892

8993
/// HKDF modes of operation.
@@ -159,6 +163,26 @@ impl PkeyCtx<()> {
159163
Ok(PkeyCtx::from_ptr(ptr))
160164
}
161165
}
166+
167+
/// Creates a new pkey context from the algorithm name.
168+
#[corresponds(EVP_PKEY_CTX_new_from_name)]
169+
#[cfg(ossl300)]
170+
pub fn new_from_name(
171+
libctx: Option<&LibCtxRef>,
172+
name: &str,
173+
propquery: Option<&str>,
174+
) -> Result<Self, ErrorStack> {
175+
unsafe {
176+
let propquery = propquery.map(|s| CString::new(s).unwrap());
177+
let name = CString::new(name).unwrap();
178+
let ptr = cvt_p(ffi::EVP_PKEY_CTX_new_from_name(
179+
libctx.map_or(ptr::null_mut(), ForeignTypeRef::as_ptr),
180+
name.as_ptr(),
181+
propquery.map_or(ptr::null_mut(), |s| s.as_ptr()),
182+
))?;
183+
Ok(PkeyCtx::from_ptr(ptr))
184+
}
185+
}
162186
}
163187

164188
impl<T> PkeyCtxRef<T>
@@ -187,6 +211,26 @@ where
187211
Ok(())
188212
}
189213

214+
/// Prepares the context for signature verification over a message
215+
/// using the public key.
216+
#[cfg(ossl340)]
217+
#[corresponds(EVP_PKEY_verify_message_init)]
218+
#[inline]
219+
pub fn verify_message_init(
220+
&mut self,
221+
algo: &mut crate::signature::Signature,
222+
) -> Result<(), ErrorStack> {
223+
unsafe {
224+
cvt(ffi::EVP_PKEY_verify_message_init(
225+
self.as_ptr(),
226+
algo.as_ptr(),
227+
ptr::null(),
228+
))?;
229+
}
230+
231+
Ok(())
232+
}
233+
190234
/// Prepares the context for signature recovery using the public key.
191235
#[corresponds(EVP_PKEY_verify_recover_init)]
192236
#[inline]
@@ -319,6 +363,25 @@ where
319363
Ok(())
320364
}
321365

366+
/// Prepares the context for signing a message using the private key.
367+
#[cfg(ossl340)]
368+
#[corresponds(EVP_PKEY_sign_message_init)]
369+
#[inline]
370+
pub fn sign_message_init(
371+
&mut self,
372+
algo: &mut crate::signature::Signature,
373+
) -> Result<(), ErrorStack> {
374+
unsafe {
375+
cvt(ffi::EVP_PKEY_sign_message_init(
376+
self.as_ptr(),
377+
algo.as_ptr(),
378+
ptr::null(),
379+
))?;
380+
}
381+
382+
Ok(())
383+
}
384+
322385
/// Sets the peer key used for secret derivation.
323386
#[corresponds(EVP_PKEY_derive_set_peer)]
324387
pub fn derive_set_peer<U>(&mut self, key: &PKeyRef<U>) -> Result<(), ErrorStack>
@@ -889,6 +952,20 @@ impl<T> PkeyCtxRef<T> {
889952
Ok(())
890953
}
891954

955+
/// Generates a new public/private keypair.
956+
///
957+
/// New OpenSSL 3.0 function that should do the same thing as keygen()
958+
#[corresponds(EVP_PKEY_generate)]
959+
#[cfg(ossl300)]
960+
#[inline]
961+
pub fn generate(&mut self) -> Result<PKey<Private>, ErrorStack> {
962+
unsafe {
963+
let mut key = ptr::null_mut();
964+
cvt(ffi::EVP_PKEY_generate(self.as_ptr(), &mut key))?;
965+
Ok(PKey::from_ptr(key))
966+
}
967+
}
968+
892969
/// Gets the nonce type for a private key context.
893970
///
894971
/// The nonce for DSA and ECDSA can be either random (the default) or deterministic (as defined by RFC 6979).
@@ -913,6 +990,14 @@ impl<T> PkeyCtxRef<T> {
913990
}
914991
Ok(NonceType(nonce_type))
915992
}
993+
994+
/// Initializes a conversion from `OsslParam` to `PKey` on given `PkeyCtx`.
995+
#[corresponds(EVP_PKEY_fromdata_init)]
996+
#[cfg(ossl300)]
997+
pub fn fromdata_init(&mut self) -> Result<(), ErrorStack> {
998+
unsafe { cvt(ffi::EVP_PKEY_fromdata_init(self.as_ptr()))? };
999+
Ok(())
1000+
}
9161001
}
9171002

9181003
#[cfg(test)]

0 commit comments

Comments
 (0)