@@ -25,14 +25,23 @@ impl Drop for EvpKdfCtx {
2525cfg_if:: cfg_if! {
2626 if #[ cfg( all( ossl320, not( osslconf = "OPENSSL_NO_ARGON2" ) ) ) ] {
2727 use std:: cmp;
28- use std:: ffi:: c_void;
29- use std:: mem:: MaybeUninit ;
3028 use std:: ptr;
3129 use foreign_types:: ForeignTypeRef ;
3230 use libc:: c_char;
3331 use crate :: { cvt, cvt_p} ;
3432 use crate :: lib_ctx:: LibCtxRef ;
3533 use crate :: error:: ErrorStack ;
34+ use crate :: ossl_param:: OsslParamBuilder ;
35+
36+ const OSSL_KDF_PARAM_PASSWORD : & [ u8 ; 5 ] = b"pass\0 " ;
37+ const OSSL_KDF_PARAM_SALT : & [ u8 ; 5 ] = b"salt\0 " ;
38+ const OSSL_KDF_PARAM_SECRET : & [ u8 ; 7 ] = b"secret\0 " ;
39+ const OSSL_KDF_PARAM_ITER : & [ u8 ; 5 ] = b"iter\0 " ;
40+ const OSSL_KDF_PARAM_SIZE : & [ u8 ; 5 ] = b"size\0 " ;
41+ const OSSL_KDF_PARAM_THREADS : & [ u8 ; 8 ] = b"threads\0 " ;
42+ const OSSL_KDF_PARAM_ARGON2_AD : & [ u8 ; 3 ] = b"ad\0 " ;
43+ const OSSL_KDF_PARAM_ARGON2_LANES : & [ u8 ; 6 ] = b"lanes\0 " ;
44+ const OSSL_KDF_PARAM_ARGON2_MEMCOST : & [ u8 ; 8 ] = b"memcost\0 " ;
3645
3746 /// Derives a key using the argon2id algorithm.
3847 ///
@@ -48,72 +57,40 @@ cfg_if::cfg_if! {
4857 salt: & [ u8 ] ,
4958 ad: Option <& [ u8 ] >,
5059 secret: Option <& [ u8 ] >,
51- mut iter: u32 ,
52- mut lanes: u32 ,
53- mut memcost: u32 ,
60+ iter: u32 ,
61+ lanes: u32 ,
62+ memcost: u32 ,
5463 out: & mut [ u8 ] ,
5564 ) -> Result <( ) , ErrorStack > {
56- unsafe {
65+ let libctx = ctx. map_or( ptr:: null_mut( ) , ForeignTypeRef :: as_ptr) ;
66+ let max_threads = unsafe {
5767 ffi:: init( ) ;
58- let libctx = ctx. map_or( ptr:: null_mut( ) , ForeignTypeRef :: as_ptr) ;
59-
60- let max_threads = ffi:: OSSL_get_max_threads ( libctx) ;
61- let mut threads = 1 ;
62- // If max_threads is 0, then this isn't a threaded build.
63- // If max_threads is > u32::MAX we need to clamp since
64- // argon2id's threads parameter is a u32.
65- if max_threads > 0 {
66- threads = cmp:: min( lanes, cmp:: min( max_threads, u32 :: MAX as u64 ) as u32 ) ;
67- }
68- let mut params: [ ffi:: OSSL_PARAM ; 10 ] =
69- core:: array:: from_fn( |_| MaybeUninit :: <ffi:: OSSL_PARAM >:: zeroed( ) . assume_init( ) ) ;
70- let mut idx = 0 ;
71- params[ idx] = ffi:: OSSL_PARAM_construct_octet_string (
72- b"pass\0 " . as_ptr( ) as * const c_char,
73- pass. as_ptr( ) as * mut c_void,
74- pass. len( ) ,
75- ) ;
76- idx += 1 ;
77- params[ idx] = ffi:: OSSL_PARAM_construct_octet_string (
78- b"salt\0 " . as_ptr( ) as * const c_char,
79- salt. as_ptr( ) as * mut c_void,
80- salt. len( ) ,
81- ) ;
82- idx += 1 ;
83- params[ idx] =
84- ffi:: OSSL_PARAM_construct_uint ( b"threads\0 " . as_ptr( ) as * const c_char, & mut threads) ;
85- idx += 1 ;
86- params[ idx] =
87- ffi:: OSSL_PARAM_construct_uint ( b"lanes\0 " . as_ptr( ) as * const c_char, & mut lanes) ;
88- idx += 1 ;
89- params[ idx] =
90- ffi:: OSSL_PARAM_construct_uint ( b"memcost\0 " . as_ptr( ) as * const c_char, & mut memcost) ;
91- idx += 1 ;
92- params[ idx] =
93- ffi:: OSSL_PARAM_construct_uint ( b"iter\0 " . as_ptr( ) as * const c_char, & mut iter) ;
94- idx += 1 ;
95- let mut size = out. len( ) as u32 ;
96- params[ idx] =
97- ffi:: OSSL_PARAM_construct_uint ( b"size\0 " . as_ptr( ) as * const c_char, & mut size) ;
98- idx += 1 ;
99- if let Some ( ad) = ad {
100- params[ idx] = ffi:: OSSL_PARAM_construct_octet_string (
101- b"ad\0 " . as_ptr( ) as * const c_char,
102- ad. as_ptr( ) as * mut c_void,
103- ad. len( ) ,
104- ) ;
105- idx += 1 ;
106- }
107- if let Some ( secret) = secret {
108- params[ idx] = ffi:: OSSL_PARAM_construct_octet_string (
109- b"secret\0 " . as_ptr( ) as * const c_char,
110- secret. as_ptr( ) as * mut c_void,
111- secret. len( ) ,
112- ) ;
113- idx += 1 ;
114- }
115- params[ idx] = ffi:: OSSL_PARAM_construct_end ( ) ;
116-
68+ ffi:: OSSL_get_max_threads ( libctx)
69+ } ;
70+ let mut threads = 1 ;
71+ // If max_threads is 0, then this isn't a threaded build.
72+ // If max_threads is > u32::MAX we need to clamp since
73+ // argon2id's threads parameter is a u32.
74+ if max_threads > 0 {
75+ threads = cmp:: min( lanes, cmp:: min( max_threads, u32 :: MAX as u64 ) as u32 ) ;
76+ }
77+ let bld = OsslParamBuilder :: new( ) ?;
78+ bld. add_octet_string( OSSL_KDF_PARAM_PASSWORD , pass) ?;
79+ bld. add_octet_string( OSSL_KDF_PARAM_SALT , salt) ?;
80+ bld. add_uint( OSSL_KDF_PARAM_THREADS , threads) ?;
81+ bld. add_uint( OSSL_KDF_PARAM_ARGON2_LANES , lanes) ?;
82+ bld. add_uint( OSSL_KDF_PARAM_ARGON2_MEMCOST , memcost) ?;
83+ bld. add_uint( OSSL_KDF_PARAM_ITER , iter) ?;
84+ let size = out. len( ) as u32 ;
85+ bld. add_uint( OSSL_KDF_PARAM_SIZE , size) ?;
86+ if let Some ( ad) = ad {
87+ bld. add_octet_string( OSSL_KDF_PARAM_ARGON2_AD , ad) ?;
88+ }
89+ if let Some ( secret) = secret {
90+ bld. add_octet_string( OSSL_KDF_PARAM_SECRET , secret) ?;
91+ }
92+ let params = bld. to_param( ) ?;
93+ unsafe {
11794 let argon2 = EvpKdf ( cvt_p( ffi:: EVP_KDF_fetch (
11895 libctx,
11996 b"ARGON2ID\0 " . as_ptr( ) as * const c_char,
0 commit comments