Skip to main content

crypto_hkdf/
material.rs

1// SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
2//
3// SPDX-License-Identifier: Apache-2.0
4
5use zeroize::{Zeroize, ZeroizeOnDrop};
6
7/// HKDF input keying material, zeroized on drop.
8#[derive(Zeroize, ZeroizeOnDrop)]
9pub struct HkdfInputKeyMaterial {
10    bytes: Vec<u8>,
11}
12
13impl HkdfInputKeyMaterial {
14    /// Build input keying material by copying the given bytes.
15    pub fn from_slice(input: &[u8]) -> Self {
16        Self {
17            bytes: input.to_vec(),
18        }
19    }
20
21    /// Borrow the input keying material bytes.
22    pub fn as_bytes(&self) -> &[u8] {
23        &self.bytes
24    }
25}
26
27/// Optional HKDF salt value, zeroized on drop.
28///
29/// HKDF salts can carry protocol or user correlation material. The wrapper
30/// deliberately has no `Debug` or `Clone` implementation so accidental logs
31/// and unmanaged duplicate buffers are not part of the public API.
32#[derive(Zeroize, ZeroizeOnDrop)]
33pub struct HkdfSalt {
34    bytes: Vec<u8>,
35}
36
37impl HkdfSalt {
38    /// Build an HKDF salt by copying the given bytes.
39    pub fn from_slice(input: &[u8]) -> Self {
40        Self {
41            bytes: input.to_vec(),
42        }
43    }
44
45    /// Borrow the salt bytes.
46    pub fn as_bytes(&self) -> &[u8] {
47        &self.bytes
48    }
49}
50
51/// HKDF `info` context/application-binding value.
52#[derive(Debug, Clone, PartialEq, Eq)]
53pub struct HkdfInfo {
54    bytes: Vec<u8>,
55}
56
57impl HkdfInfo {
58    /// Build an HKDF `info` value by copying the given bytes.
59    pub fn from_slice(input: &[u8]) -> Self {
60        Self {
61            bytes: input.to_vec(),
62        }
63    }
64
65    /// Borrow the `info` bytes.
66    pub fn as_bytes(&self) -> &[u8] {
67        &self.bytes
68    }
69
70    pub(crate) fn from_vec(bytes: Vec<u8>) -> Self {
71        Self { bytes }
72    }
73}
74
75/// Fixed-length HKDF output keying material, zeroized on drop.
76#[derive(Zeroize, ZeroizeOnDrop)]
77pub struct HkdfOutput<const N: usize> {
78    bytes: [u8; N],
79}
80
81impl<const N: usize> HkdfOutput<N> {
82    /// Borrow the `N`-byte derived output.
83    pub fn as_bytes(&self) -> &[u8; N] {
84        &self.bytes
85    }
86
87    /// Consume the output and return its `N`-byte array.
88    ///
89    /// The returned array is no longer zeroized by this type. Callers must wipe
90    /// it as soon as the derived key material is no longer needed.
91    pub fn into_bytes(mut self) -> [u8; N] {
92        let output = self.bytes;
93        self.bytes.zeroize();
94        output
95    }
96
97    pub(crate) fn from_array(bytes: [u8; N]) -> Self {
98        Self { bytes }
99    }
100}