Skip to main content

security/
key_derivation.rs

1use serde_json::Value;
2
3use crate::bridge;
4use crate::error::Result;
5
6#[derive(Debug)]
7pub struct DerivedKey {
8    handle: bridge::Handle,
9}
10
11impl DerivedKey {
12    pub fn attributes(&self) -> Result<Value> {
13        let mut status = 0;
14        let mut error = std::ptr::null_mut();
15        let raw = unsafe {
16            bridge::security_key_copy_attributes(self.handle.as_ptr(), &mut status, &mut error)
17        };
18        bridge::required_json("security_key_copy_attributes", raw, status, error)
19    }
20}
21
22pub struct KeyDerivation;
23
24impl KeyDerivation {
25    pub fn derive_pbkdf2_sha256(
26        password: &str,
27        salt: &[u8],
28        rounds: u32,
29        key_size_bits: usize,
30    ) -> Result<DerivedKey> {
31        let password = bridge::cstring(password)?;
32        let mut status = 0;
33        let mut error = std::ptr::null_mut();
34        let raw = unsafe {
35            bridge::security_key_derivation_derive_pbkdf2_sha256(
36                password.as_ptr(),
37                salt.as_ptr().cast(),
38                bridge::len_to_isize(salt.len())?,
39                isize::try_from(rounds).map_err(|_| {
40                    crate::error::SecurityError::InvalidArgument(
41                        "round count exceeds bridge size limits".to_owned(),
42                    )
43                })?,
44                bridge::len_to_isize(key_size_bits)?,
45                &mut status,
46                &mut error,
47            )
48        };
49        bridge::required_handle(
50            "security_key_derivation_derive_pbkdf2_sha256",
51            raw,
52            status,
53            error,
54        )
55        .map(|handle| DerivedKey { handle })
56    }
57}