diff --git a/openssl-sys/src/ec.rs b/openssl-sys/src/ec.rs index 995a84ff6..61fa0b134 100644 --- a/openssl-sys/src/ec.rs +++ b/openssl-sys/src/ec.rs @@ -5,6 +5,20 @@ use super::*; pub const OPENSSL_EC_NAMED_CURVE: c_int = 1; +cfg_if! { + if #[cfg(not(ossl300))] { + pub unsafe fn EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx: *mut EVP_PKEY_CTX, nid: c_int) -> c_int { + EVP_PKEY_CTX_ctrl( + ctx, + EVP_PKEY_EC, + EVP_PKEY_OP_PARAMGEN|EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, + nid, + ptr::null_mut(), + ) + } + } +} #[cfg(ossl300)] pub unsafe fn EVP_EC_gen(curve: *const c_char) -> *mut EVP_PKEY { EVP_PKEY_Q_keygen( @@ -14,3 +28,5 @@ pub unsafe fn EVP_EC_gen(curve: *const c_char) -> *mut EVP_PKEY { curve, ) } + +pub const EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID: c_int = EVP_PKEY_ALG_CTRL + 1; diff --git a/openssl-sys/src/handwritten/ec.rs b/openssl-sys/src/handwritten/ec.rs index 849251000..37bf3a540 100644 --- a/openssl-sys/src/handwritten/ec.rs +++ b/openssl-sys/src/handwritten/ec.rs @@ -1,6 +1,11 @@ use super::super::*; use libc::*; +#[cfg(ossl300)] +extern "C" { + pub fn EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx: *mut EVP_PKEY_CTX, nid: c_int) -> c_int; +} + #[repr(C)] #[derive(Copy, Clone)] pub enum point_conversion_form_t { diff --git a/openssl/src/pkey_ctx.rs b/openssl/src/pkey_ctx.rs index 91bbf5890..6a4f6e1bd 100644 --- a/openssl/src/pkey_ctx.rs +++ b/openssl/src/pkey_ctx.rs @@ -68,6 +68,7 @@ let cmac_key = ctx.keygen().unwrap(); use crate::cipher::CipherRef; use crate::error::ErrorStack; use crate::md::MdRef; +use crate::nid::Nid; use crate::pkey::{HasPrivate, HasPublic, Id, PKey, PKeyRef, Params, Private}; use crate::rsa::Padding; use crate::sign::RsaPssSaltlen; @@ -463,6 +464,22 @@ impl PkeyCtxRef { Ok(()) } + /// Sets the EC paramgen curve NID. + /// + /// This is only useful for EC keys. + #[corresponds(EVP_PKEY_CTX_set_ec_paramgen_curve_nid)] + #[inline] + pub fn set_ec_paramgen_curve_nid(&mut self, nid: Nid) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_PKEY_CTX_set_ec_paramgen_curve_nid( + self.as_ptr(), + nid.as_raw(), + ))?; + } + + Ok(()) + } + /// Returns the RSA padding mode in use. /// /// This is only useful for RSA keys. @@ -983,6 +1000,17 @@ mod test { assert_eq!(params.size(), size); } + #[test] + fn ec_keygen() { + let mut ctx = PkeyCtx::new_id(Id::EC).unwrap(); + ctx.paramgen_init().unwrap(); + ctx.set_ec_paramgen_curve_nid(Nid::X9_62_PRIME256V1) + .unwrap(); + let params = ctx.paramgen().unwrap(); + + assert_eq!(params.size(), 72); + } + #[test] #[cfg(any(ossl110, boringssl, libressl360, awslc))] fn hkdf() {