Skip to main content

security/
key_derivation.rs

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