libsignal_protocol/
hkdf.rs1use crate::{
2 context::ContextInner,
3 errors::{FromInternalErrorCode, InternalError},
4 raw_ptr::Raw,
5 Context,
6};
7use failure::Error;
8use std::{ptr, rc::Rc};
9
10#[derive(Debug, Clone)]
12pub struct HMACBasedKeyDerivationFunction {
13 pub(crate) raw: Raw<sys::hkdf_context>,
14 ctx: Rc<ContextInner>,
15}
16
17impl HMACBasedKeyDerivationFunction {
18 pub(crate) fn new(
19 version: i32,
20 ctx: &Context,
21 ) -> Result<HMACBasedKeyDerivationFunction, Error> {
22 unsafe {
23 let mut raw = ptr::null_mut();
24 sys::hkdf_create(&mut raw, version as _, ctx.raw())
25 .into_result()?;
26
27 Ok(HMACBasedKeyDerivationFunction {
28 raw: Raw::from_ptr(raw),
29 ctx: Rc::clone(&ctx.0),
30 })
31 }
32 }
33
34 pub fn derive_secrets(
37 &self,
38 secret_length: usize,
39 input_key_material: &[u8],
40 salt: &[u8],
41 info: &[u8],
42 ) -> Result<Vec<u8>, Error> {
43 unsafe {
44 let mut secret = ptr::null_mut();
45 let prk_len = sys::hkdf_derive_secrets(
46 self.raw.as_ptr(),
47 &mut secret,
48 input_key_material.as_ptr(),
49 input_key_material.len(),
50 salt.as_ptr(),
51 salt.len(),
52 info.as_ptr(),
53 info.len(),
54 secret_length,
55 );
56
57 if prk_len < 0 {
58 return Err(InternalError::from_error_code(prk_len as i32)
59 .unwrap_or(InternalError::Unknown)
60 .into());
61 }
62
63 let secret = std::slice::from_raw_parts_mut(secret, secret_length);
67 Ok(Vec::from(Box::from_raw(secret)))
68 }
69 }
70}