Skip to content

Commit 16d071a

Browse files
committed
kdf: use ParamBuilder
Increases the safety of the code and, imho, increases the readability. Additionally, removes the need for iter, lanes & memcost to be mutable.
1 parent f2cea2b commit 16d071a

File tree

1 file changed

+40
-77
lines changed

1 file changed

+40
-77
lines changed

openssl/src/kdf.rs

Lines changed: 40 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,14 @@ impl Drop for EvpKdfCtx {
2525
cfg_if::cfg_if! {
2626
if #[cfg(all(ossl320, not(osslconf = "OPENSSL_NO_ARGON2")))] {
2727
use std::cmp;
28-
use std::ffi::c_void;
2928
use std::ffi::CStr;
30-
use std::mem::MaybeUninit;
3129
use std::ptr;
3230
use foreign_types::ForeignTypeRef;
33-
use libc::c_char;
3431
use crate::{cvt, cvt_p};
3532
use crate::lib_ctx::LibCtxRef;
3633
use crate::error::ErrorStack;
34+
use crate::params::ParamBuilder;
35+
use crate::util::c_str;
3736

3837
#[allow(clippy::too_many_arguments)]
3938
pub fn argon2d(
@@ -94,86 +93,50 @@ cfg_if::cfg_if! {
9493
salt: &[u8],
9594
ad: Option<&[u8]>,
9695
secret: Option<&[u8]>,
97-
mut iter: u32,
98-
mut lanes: u32,
99-
mut memcost: u32,
96+
iter: u32,
97+
lanes: u32,
98+
memcost: u32,
10099
out: &mut [u8],
101100
) -> Result<(), ErrorStack> {
102-
unsafe {
103-
ffi::init();
104-
let libctx = ctx.map_or(ptr::null_mut(), ForeignTypeRef::as_ptr);
105-
106-
let max_threads = ffi::OSSL_get_max_threads(libctx);
107-
let mut threads = 1;
108-
// If max_threads is 0, then this isn't a threaded build.
109-
// If max_threads is > u32::MAX we need to clamp since
110-
// argon2's threads parameter is a u32.
111-
if max_threads > 0 {
112-
threads = cmp::min(lanes, cmp::min(max_threads, u32::MAX as u64) as u32);
113-
}
114-
let mut params: [ffi::OSSL_PARAM; 10] =
115-
core::array::from_fn(|_| MaybeUninit::<ffi::OSSL_PARAM>::zeroed().assume_init());
116-
let mut idx = 0;
117-
params[idx] = ffi::OSSL_PARAM_construct_octet_string(
118-
b"pass\0".as_ptr() as *const c_char,
119-
pass.as_ptr() as *mut c_void,
120-
pass.len(),
121-
);
122-
idx += 1;
123-
params[idx] = ffi::OSSL_PARAM_construct_octet_string(
124-
b"salt\0".as_ptr() as *const c_char,
125-
salt.as_ptr() as *mut c_void,
126-
salt.len(),
127-
);
128-
idx += 1;
129-
params[idx] =
130-
ffi::OSSL_PARAM_construct_uint(b"threads\0".as_ptr() as *const c_char, &mut threads);
131-
idx += 1;
132-
params[idx] =
133-
ffi::OSSL_PARAM_construct_uint(b"lanes\0".as_ptr() as *const c_char, &mut lanes);
134-
idx += 1;
135-
params[idx] =
136-
ffi::OSSL_PARAM_construct_uint(b"memcost\0".as_ptr() as *const c_char, &mut memcost);
137-
idx += 1;
138-
params[idx] =
139-
ffi::OSSL_PARAM_construct_uint(b"iter\0".as_ptr() as *const c_char, &mut iter);
140-
idx += 1;
141-
let mut size = out.len() as u32;
142-
params[idx] =
143-
ffi::OSSL_PARAM_construct_uint(b"size\0".as_ptr() as *const c_char, &mut size);
144-
idx += 1;
145-
if let Some(ad) = ad {
146-
params[idx] = ffi::OSSL_PARAM_construct_octet_string(
147-
b"ad\0".as_ptr() as *const c_char,
148-
ad.as_ptr() as *mut c_void,
149-
ad.len(),
150-
);
151-
idx += 1;
152-
}
153-
if let Some(secret) = secret {
154-
params[idx] = ffi::OSSL_PARAM_construct_octet_string(
155-
b"secret\0".as_ptr() as *const c_char,
156-
secret.as_ptr() as *mut c_void,
157-
secret.len(),
158-
);
159-
idx += 1;
160-
}
161-
params[idx] = ffi::OSSL_PARAM_construct_end();
101+
ffi::init();
102+
let libctx = ctx.map_or(ptr::null_mut(), ForeignTypeRef::as_ptr);
103+
104+
let max_threads = unsafe { ffi::OSSL_get_max_threads(libctx) };
105+
let mut threads = 1;
106+
// If max_threads is 0, then this isn't a threaded build.
107+
// If max_threads is > u32::MAX we need to clamp since
108+
// argon2's threads parameter is a u32.
109+
if max_threads > 0 {
110+
threads = cmp::min(lanes, cmp::min(max_threads, u32::MAX as u64) as u32);
111+
}
112+
let mut param_builder = ParamBuilder::new()
113+
.push_byte_string(c_str(b"pass\0"), pass)?
114+
.push_byte_string(c_str(b"salt\0"), salt)?
115+
.push_uint(c_str(b"threads\0"), threads)?
116+
.push_uint(c_str(b"lanes\0"), lanes)?
117+
.push_uint(c_str(b"memcost\0"), memcost)?
118+
.push_uint(c_str(b"iter\0"), iter)?
119+
.push_size_t(c_str(b"size\0"), out.len())?;
120+
if let Some(ad) = ad {
121+
param_builder = param_builder.push_byte_string(c_str(b"ad\0"), ad)?;
122+
}
123+
if let Some(secret) = secret {
124+
param_builder = param_builder.push_byte_string(c_str(b"secret\0"), secret)?;
125+
}
162126

163-
let argon2 = EvpKdf(cvt_p(ffi::EVP_KDF_fetch(
164-
libctx,
165-
kdf_identifier.as_ptr() as *const c_char,
166-
ptr::null(),
167-
))?);
168-
let ctx = EvpKdfCtx(cvt_p(ffi::EVP_KDF_CTX_new(argon2.0))?);
169-
cvt(ffi::EVP_KDF_derive(
127+
let argon2 = EvpKdf(cvt_p(unsafe {
128+
ffi::EVP_KDF_fetch(libctx, kdf_identifier.as_ptr(), ptr::null())
129+
})?);
130+
let ctx = EvpKdfCtx(cvt_p(unsafe { ffi::EVP_KDF_CTX_new(argon2.0) })?);
131+
cvt(unsafe {
132+
ffi::EVP_KDF_derive(
170133
ctx.0,
171134
out.as_mut_ptr(),
172135
out.len(),
173-
params.as_ptr(),
174-
))
175-
.map(|_| ())
176-
}
136+
param_builder.build()?.as_ptr(),
137+
)
138+
})
139+
.map(|_| ())
177140
}
178141
}
179142
}

0 commit comments

Comments
 (0)