@@ -68,7 +68,7 @@ let cmac_key = ctx.keygen().unwrap();
6868use  crate :: cipher:: CipherRef ; 
6969use  crate :: error:: ErrorStack ; 
7070use  crate :: md:: MdRef ; 
71- use  crate :: pkey:: { HasPrivate ,  HasPublic ,  Id ,  PKey ,  PKeyRef ,  Private } ; 
71+ use  crate :: pkey:: { HasPrivate ,  HasPublic ,  Id ,  PKey ,  PKeyRef ,  Params ,   Private } ; 
7272use  crate :: rsa:: Padding ; 
7373use  crate :: sign:: RsaPssSaltlen ; 
7474use  crate :: { cvt,  cvt_p} ; 
@@ -420,6 +420,17 @@ impl<T> PkeyCtxRef<T> {
420420        Ok ( ( ) ) 
421421    } 
422422
423+     /// Prepares the context for key parameter generation. 
424+      #[ corresponds( EVP_PKEY_paramgen_init ) ]  
425+     #[ inline]  
426+     pub  fn  paramgen_init ( & mut  self )  -> Result < ( ) ,  ErrorStack >  { 
427+         unsafe  { 
428+             cvt ( ffi:: EVP_PKEY_paramgen_init ( self . as_ptr ( ) ) ) ?; 
429+         } 
430+ 
431+         Ok ( ( ) ) 
432+     } 
433+ 
423434    /// Sets which algorithm was used to compute the digest used in a 
424435     /// signature. With RSA signatures this causes the signature to be wrapped 
425436     /// in a `DigestInfo` structure. This is almost always what you want with 
@@ -436,6 +447,22 @@ impl<T> PkeyCtxRef<T> {
436447        Ok ( ( ) ) 
437448    } 
438449
450+     /// Sets the DSA paramgen bits. 
451+      /// 
452+      /// This is only useful for DSA keys. 
453+      #[ corresponds( EVP_PKEY_CTX_set_dsa_paramgen_bits ) ]  
454+     #[ inline]  
455+     pub  fn  set_dsa_paramgen_bits ( & mut  self ,  bits :  u32 )  -> Result < ( ) ,  ErrorStack >  { 
456+         unsafe  { 
457+             cvt ( ffi:: EVP_PKEY_CTX_set_dsa_paramgen_bits ( 
458+                 self . as_ptr ( ) , 
459+                 bits as  i32 , 
460+             ) ) ?; 
461+         } 
462+ 
463+         Ok ( ( ) ) 
464+     } 
465+ 
439466    /// Returns the RSA padding mode in use. 
440467     /// 
441468     /// This is only useful for RSA keys. 
@@ -734,6 +761,17 @@ impl<T> PkeyCtxRef<T> {
734761        } 
735762    } 
736763
764+     /// Generates a new set of key parameters. 
765+      #[ corresponds( EVP_PKEY_paramgen ) ]  
766+     #[ inline]  
767+     pub  fn  paramgen ( & mut  self )  -> Result < PKey < Params > ,  ErrorStack >  { 
768+         unsafe  { 
769+             let  mut  key = ptr:: null_mut ( ) ; 
770+             cvt ( ffi:: EVP_PKEY_paramgen ( self . as_ptr ( ) ,  & mut  key) ) ?; 
771+             Ok ( PKey :: from_ptr ( key) ) 
772+         } 
773+     } 
774+ 
737775    /// Sets the nonce type for a private key context. 
738776     /// 
739777     /// The nonce for DSA and ECDSA can be either random (the default) or deterministic (as defined by RFC 6979). 
@@ -794,6 +832,8 @@ mod test {
794832    use  crate :: pkey:: PKey ; 
795833    use  crate :: rsa:: Rsa ; 
796834    use  crate :: sign:: Verifier ; 
835+     #[ cfg( not( boringssl) ) ]  
836+     use  cfg_if:: cfg_if; 
797837
798838    #[ test]  
799839    fn  rsa ( )  { 
@@ -920,6 +960,29 @@ mod test {
920960        ctx. keygen ( ) . unwrap ( ) ; 
921961    } 
922962
963+     #[ test]  
964+     #[ cfg( not( boringssl) ) ]  
965+     fn  dsa_paramgen ( )  { 
966+         let  mut  ctx = PkeyCtx :: new_id ( Id :: DSA ) . unwrap ( ) ; 
967+         ctx. paramgen_init ( ) . unwrap ( ) ; 
968+         ctx. set_dsa_paramgen_bits ( 2048 ) . unwrap ( ) ; 
969+         let  params = ctx. paramgen ( ) . unwrap ( ) ; 
970+ 
971+         let  size = { 
972+             cfg_if !  { 
973+                 if  #[ cfg( awslc) ]  { 
974+                     72 
975+                 }  else if  #[ cfg( any( libressl,  all( ossl101,  not( ossl102) ) ) ) ]  { 
976+                     // LibreSSL and OpenSSL 1.0.1 and earlier 
977+                     48 
978+                 }  else { 
979+                     64 
980+                 } 
981+             } 
982+         } ; 
983+         assert_eq ! ( params. size( ) ,  size) ; 
984+     } 
985+ 
923986    #[ test]  
924987    #[ cfg( any( ossl110,  boringssl,  libressl360,  awslc) ) ]  
925988    fn  hkdf ( )  { 
0 commit comments