@@ -25,14 +25,23 @@ impl Drop for EvpKdfCtx {
25
25
cfg_if:: cfg_if! {
26
26
if #[ cfg( all( ossl320, not( osslconf = "OPENSSL_NO_ARGON2" ) ) ) ] {
27
27
use std:: cmp;
28
- use std:: ffi:: c_void;
29
- use std:: mem:: MaybeUninit ;
30
28
use std:: ptr;
31
29
use foreign_types:: ForeignTypeRef ;
32
30
use libc:: c_char;
33
31
use crate :: { cvt, cvt_p} ;
34
32
use crate :: lib_ctx:: LibCtxRef ;
35
33
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 " ;
36
45
37
46
/// Derives a key using the argon2id algorithm.
38
47
///
@@ -48,72 +57,40 @@ cfg_if::cfg_if! {
48
57
salt: & [ u8 ] ,
49
58
ad: Option <& [ u8 ] >,
50
59
secret: Option <& [ u8 ] >,
51
- mut iter: u32 ,
52
- mut lanes: u32 ,
53
- mut memcost: u32 ,
60
+ iter: u32 ,
61
+ lanes: u32 ,
62
+ memcost: u32 ,
54
63
out: & mut [ u8 ] ,
55
64
) -> Result <( ) , ErrorStack > {
56
- unsafe {
65
+ let libctx = ctx. map_or( ptr:: null_mut( ) , ForeignTypeRef :: as_ptr) ;
66
+ let max_threads = unsafe {
57
67
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 {
117
94
let argon2 = EvpKdf ( cvt_p( ffi:: EVP_KDF_fetch (
118
95
libctx,
119
96
b"ARGON2ID\0 " . as_ptr( ) as * const c_char,
0 commit comments