diff --git a/src/hkdf.rs b/src/hkdf.rs | |
new file mode 100644 | |
index 0000000..cc7e5b3 | |
--- /dev/null | |
+++ b/src/hkdf.rs | |
@@ -0,0 +1,89 @@ | |
+use crate::cvt; | |
+use crate::error::ErrorStack; | |
+use crate::md::MdRef; | |
+use foreign_types::ForeignTypeRef; | |
+use openssl_macros::corresponds; | |
+ | |
+/// Computes HKDF (as specified by RFC 5869). | |
+/// | |
+/// HKDF is an Extract-and-Expand algorithm. It does not do any key stretching, | |
+/// and as such, is not suited to be used alone to generate a key from a | |
+/// password. | |
+#[corresponds(HKDF)] | |
+#[inline] | |
+pub fn hkdf( | |
+ out_key: &mut [u8], | |
+ md: &MdRef, | |
+ secret: &[u8], | |
+ salt: &[u8], | |
+ info: &[u8], | |
+) -> Result<(), ErrorStack> { | |
+ unsafe { | |
+ cvt(ffi::HKDF( | |
+ out_key.as_mut_ptr(), | |
+ out_key.len(), | |
+ md.as_ptr(), | |
+ secret.as_ptr(), | |
+ secret.len(), | |
+ salt.as_ptr(), | |
+ salt.len(), | |
+ info.as_ptr(), | |
+ info.len(), | |
+ ))?; | |
+ } | |
+ | |
+ Ok(()) | |
+} | |
+ | |
+/// Computes a HKDF PRK (as specified by RFC 5869). | |
+/// | |
+/// WARNING: This function orders the inputs differently from RFC 5869 | |
+/// specification. Double-check which parameter is the secret/IKM and which is | |
+/// the salt when using. | |
+#[corresponds(HKDF_extract)] | |
+#[inline] | |
+pub fn hkdf_extract<'a>( | |
+ out_key: &'a mut [u8], | |
+ md: &MdRef, | |
+ secret: &[u8], | |
+ salt: &[u8], | |
+) -> Result<&'a [u8], ErrorStack> { | |
+ let mut out_len = out_key.len(); | |
+ unsafe { | |
+ cvt(ffi::HKDF_extract( | |
+ out_key.as_mut_ptr(), | |
+ &mut out_len, | |
+ md.as_ptr(), | |
+ secret.as_ptr(), | |
+ secret.len(), | |
+ salt.as_ptr(), | |
+ salt.len(), | |
+ ))?; | |
+ } | |
+ | |
+ Ok(&out_key[..out_len]) | |
+} | |
+ | |
+/// Computes a HKDF OKM (as specified by RFC 5869). | |
+#[corresponds(HKDF_expand)] | |
+#[inline] | |
+pub fn hkdf_expand( | |
+ out_key: &mut [u8], | |
+ md: &MdRef, | |
+ prk: &[u8], | |
+ info: &[u8], | |
+) -> Result<(), ErrorStack> { | |
+ unsafe { | |
+ cvt(ffi::HKDF_expand( | |
+ out_key.as_mut_ptr(), | |
+ out_key.len(), | |
+ md.as_ptr(), | |
+ prk.as_ptr(), | |
+ prk.len(), | |
+ info.as_ptr(), | |
+ info.len(), | |
+ ))?; | |
+ } | |
+ | |
+ Ok(()) | |
+} |